@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
package/dist/scripts/signals.js
CHANGED
|
@@ -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();
|
|
@@ -1635,9 +1650,9 @@ var import_chalk7 = __toESM(require("chalk"));
|
|
|
1635
1650
|
var import_connectors6 = require("@tradejs/node/connectors");
|
|
1636
1651
|
var import_cli2 = require("@tradejs/node/cli");
|
|
1637
1652
|
var import_async3 = require("@tradejs/core/async");
|
|
1638
|
-
var
|
|
1653
|
+
var import_strategies3 = require("@tradejs/core/strategies");
|
|
1639
1654
|
var import_constants3 = require("@tradejs/core/constants");
|
|
1640
|
-
var
|
|
1655
|
+
var import_strategies4 = require("@tradejs/node/strategies");
|
|
1641
1656
|
var import_time3 = require("@tradejs/core/time");
|
|
1642
1657
|
var import_logger4 = require("@tradejs/infra/logger");
|
|
1643
1658
|
var import_redis5 = require("@tradejs/infra/redis");
|
|
@@ -1649,6 +1664,7 @@ var import_time = require("@tradejs/core/time");
|
|
|
1649
1664
|
var SECONDS_PER_DAY = 86400;
|
|
1650
1665
|
var RUNTIME_SIGNAL_RETENTION_DAYS_ENV = "RUNTIME_SIGNAL_RETENTION_DAYS";
|
|
1651
1666
|
var DEFAULT_RUNTIME_SIGNAL_RETENTION_TTL_SECONDS = import_constants.TTL_3D;
|
|
1667
|
+
var RUNTIME_LINEAGE_SCOPE_RETENTION_TTL_SECONDS = import_constants.TTL_1M;
|
|
1652
1668
|
var parsePositiveNumber = (value) => {
|
|
1653
1669
|
if (value == null || value === "") {
|
|
1654
1670
|
return null;
|
|
@@ -1810,6 +1826,7 @@ var import_progress = __toESM(require("progress"));
|
|
|
1810
1826
|
var import_chalk = __toESM(require("chalk"));
|
|
1811
1827
|
var import_connectors = require("@tradejs/connectors");
|
|
1812
1828
|
var import_connectors2 = require("@tradejs/node/connectors");
|
|
1829
|
+
var import_strategies = require("@tradejs/node/strategies");
|
|
1813
1830
|
var import_timescale = require("@tradejs/infra/timescale");
|
|
1814
1831
|
|
|
1815
1832
|
// src/lib/binanceMarketData.ts
|
|
@@ -1819,14 +1836,6 @@ var MARKET_FEATURE_INTERVAL_MS = {
|
|
|
1819
1836
|
"15m": 9e5,
|
|
1820
1837
|
"1h": 36e5
|
|
1821
1838
|
};
|
|
1822
|
-
var STABLE_QUOTE_SYMBOLS = /* @__PURE__ */ new Set([
|
|
1823
|
-
"USDCUSDT",
|
|
1824
|
-
"FDUSDUSDT",
|
|
1825
|
-
"TUSDUSDT",
|
|
1826
|
-
"BUSDUSDT",
|
|
1827
|
-
"USDPUSDT",
|
|
1828
|
-
"DAIUSDT"
|
|
1829
|
-
]);
|
|
1830
1839
|
var safeDivide = (num, den) => Number.isFinite(num) && Number.isFinite(den) && den !== 0 ? num / den : null;
|
|
1831
1840
|
var mean = (values) => values.length ? values.reduce((sum, value) => sum + value, 0) / values.length : null;
|
|
1832
1841
|
var standardDeviation = (values) => {
|
|
@@ -1870,9 +1879,6 @@ var classifyBtcAltRegime = ({
|
|
|
1870
1879
|
if (btcVsAltReturn24h < -5e-3) return "alt_lead";
|
|
1871
1880
|
return "neutral";
|
|
1872
1881
|
};
|
|
1873
|
-
var selectBreadthUniverseFromTickers = (tickers, limit) => tickers.filter(
|
|
1874
|
-
(ticker) => ticker.symbol.endsWith("USDT") && ticker.symbol !== "BTCUSDT" && !STABLE_QUOTE_SYMBOLS.has(ticker.symbol) && Number.isFinite(ticker.turnover24h) && ticker.turnover24h > 0
|
|
1875
|
-
).sort((a, b) => b.turnover24h - a.turnover24h).slice(0, Math.max(0, limit)).map((ticker) => ticker.symbol);
|
|
1876
1882
|
var aggregateAggTradesToRows = ({
|
|
1877
1883
|
symbol,
|
|
1878
1884
|
interval: interval2,
|
|
@@ -2354,10 +2360,6 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2354
2360
|
process.env.BINANCE_MARKET_CONTEXT_TRADE_FLOW_SYMBOL_LIMIT,
|
|
2355
2361
|
2
|
|
2356
2362
|
);
|
|
2357
|
-
const breadthLimit = asInt(
|
|
2358
|
-
process.env.BINANCE_MARKET_CONTEXT_BREADTH_LIMIT,
|
|
2359
|
-
30
|
|
2360
|
-
);
|
|
2361
2363
|
const breadthChunkDays = asFloat(
|
|
2362
2364
|
process.env.BINANCE_MARKET_CONTEXT_BREADTH_CHUNK_DAYS,
|
|
2363
2365
|
30
|
|
@@ -2480,88 +2482,113 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2480
2482
|
}
|
|
2481
2483
|
}
|
|
2482
2484
|
if (includeBreadth) {
|
|
2483
|
-
const
|
|
2484
|
-
const breadthSymbols =
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
);
|
|
2488
|
-
const universe = `binance_top${breadthSymbols.length}_usdt`;
|
|
2489
|
-
const coverage = await (0, import_timescale.getMarketBreadthCoverage)({
|
|
2490
|
-
universe,
|
|
2491
|
-
interval: interval2,
|
|
2492
|
-
startMs: breadthStartMs,
|
|
2493
|
-
endMs
|
|
2494
|
-
});
|
|
2495
|
-
const hasBtcAltMetrics = (coverage?.btcAltMetricsRows ?? 0) >= Math.floor(Math.max(1, coverage?.rows ?? 0) * 0.9);
|
|
2496
|
-
if (!hasCoverage({
|
|
2497
|
-
coverage,
|
|
2485
|
+
const breadthUniverses = (0, import_strategies.getBinanceBreadthUniverses)();
|
|
2486
|
+
const breadthSymbols = breadthUniverses.at(-1)?.symbols ?? [];
|
|
2487
|
+
const connectorInterval = marketIntervalToConnectorInterval(interval2);
|
|
2488
|
+
const chunks = buildBreadthBackfillChunks({
|
|
2498
2489
|
startMs: breadthStartMs,
|
|
2499
2490
|
endMs,
|
|
2500
|
-
intervalMs: intervalMs2
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
chunks,
|
|
2511
|
-
coverage,
|
|
2512
|
-
intervalMs: intervalMs2
|
|
2513
|
-
});
|
|
2514
|
-
const bar = new import_progress.default(
|
|
2515
|
-
"breadth :current/:total [:bar][:percent] :etas(s) candles=:candles skip=:skip chunk=:chunk :symbol",
|
|
2516
|
-
{
|
|
2517
|
-
total: Math.max(1, missingChunks.length * breadthSymbols.length),
|
|
2518
|
-
width: 24
|
|
2519
|
-
}
|
|
2520
|
-
);
|
|
2521
|
-
let candlesRead = 0;
|
|
2522
|
-
let skippedBreadthChunks = chunks.length - missingChunks.length;
|
|
2523
|
-
if (!missingChunks.length) {
|
|
2524
|
-
bar.tick(1, {
|
|
2525
|
-
candles: 0,
|
|
2526
|
-
skip: skippedBreadthChunks,
|
|
2527
|
-
chunk: "cached",
|
|
2528
|
-
symbol: universe
|
|
2491
|
+
intervalMs: intervalMs2,
|
|
2492
|
+
chunkDays: breadthChunkDays
|
|
2493
|
+
});
|
|
2494
|
+
const plans = await Promise.all(
|
|
2495
|
+
breadthUniverses.map(async (definition) => {
|
|
2496
|
+
const coverage = await (0, import_timescale.getMarketBreadthCoverage)({
|
|
2497
|
+
universe: definition.universe,
|
|
2498
|
+
interval: interval2,
|
|
2499
|
+
startMs: breadthStartMs,
|
|
2500
|
+
endMs
|
|
2529
2501
|
});
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
candlesBySymbol[symbol] = candles;
|
|
2546
|
-
candlesRead += candles.length;
|
|
2547
|
-
bar.tick(1, {
|
|
2548
|
-
candles: candlesRead,
|
|
2549
|
-
skip: skippedBreadthChunks,
|
|
2550
|
-
chunk: `${originalChunkIndex + 1}/${chunks.length}`,
|
|
2551
|
-
symbol
|
|
2552
|
-
});
|
|
2502
|
+
const hasBtcAltMetrics = (coverage?.btcAltMetricsRows ?? 0) >= Math.floor(Math.max(1, coverage?.rows ?? 0) * 0.9);
|
|
2503
|
+
const missingChunks2 = !hasCoverage({
|
|
2504
|
+
coverage,
|
|
2505
|
+
startMs: breadthStartMs,
|
|
2506
|
+
endMs,
|
|
2507
|
+
intervalMs: intervalMs2
|
|
2508
|
+
}) || !hasBtcAltMetrics ? !hasBtcAltMetrics ? chunks : filterMissingBreadthBackfillChunks({
|
|
2509
|
+
chunks,
|
|
2510
|
+
coverage,
|
|
2511
|
+
intervalMs: intervalMs2
|
|
2512
|
+
}) : [];
|
|
2513
|
+
if (!missingChunks2.length) {
|
|
2514
|
+
console.log(
|
|
2515
|
+
import_chalk.default.gray(`breadth cached: universe=${definition.universe}`)
|
|
2516
|
+
);
|
|
2553
2517
|
}
|
|
2554
|
-
|
|
2555
|
-
|
|
2518
|
+
return {
|
|
2519
|
+
definition,
|
|
2520
|
+
missingChunkKeys: new Set(
|
|
2521
|
+
missingChunks2.map((chunk) => `${chunk.startMs}:${chunk.endMs}`)
|
|
2522
|
+
)
|
|
2523
|
+
};
|
|
2524
|
+
})
|
|
2525
|
+
);
|
|
2526
|
+
const missingChunks = chunks.filter((chunk) => {
|
|
2527
|
+
const key = `${chunk.startMs}:${chunk.endMs}`;
|
|
2528
|
+
return plans.some((plan) => plan.missingChunkKeys.has(key));
|
|
2529
|
+
});
|
|
2530
|
+
const bar = new import_progress.default(
|
|
2531
|
+
"breadth :current/:total [:bar][:percent] :etas(s) candles=:candles skip=:skip chunk=:chunk :symbol",
|
|
2532
|
+
{
|
|
2533
|
+
total: Math.max(1, missingChunks.length * breadthSymbols.length),
|
|
2534
|
+
width: 24
|
|
2535
|
+
}
|
|
2536
|
+
);
|
|
2537
|
+
let candlesRead = 0;
|
|
2538
|
+
const skippedBreadthChunks = chunks.length - missingChunks.length;
|
|
2539
|
+
if (!missingChunks.length) {
|
|
2540
|
+
bar.tick(1, {
|
|
2541
|
+
candles: 0,
|
|
2542
|
+
skip: skippedBreadthChunks,
|
|
2543
|
+
chunk: "cached",
|
|
2544
|
+
symbol: "top5/top10/top30/top50/top100"
|
|
2545
|
+
});
|
|
2546
|
+
}
|
|
2547
|
+
for (let chunkIndex = 0; chunkIndex < missingChunks.length; chunkIndex += 1) {
|
|
2548
|
+
const chunk = missingChunks[chunkIndex];
|
|
2549
|
+
const originalChunkIndex = chunks.findIndex(
|
|
2550
|
+
(item) => item.startMs === chunk.startMs && item.endMs === chunk.endMs
|
|
2551
|
+
);
|
|
2552
|
+
const candlesBySymbol = {};
|
|
2553
|
+
for (const symbol of breadthSymbols) {
|
|
2554
|
+
const candles = await connector.kline({
|
|
2555
|
+
symbol,
|
|
2556
2556
|
interval: connectorInterval,
|
|
2557
2557
|
start: chunk.fetchStartMs,
|
|
2558
2558
|
end: chunk.endMs,
|
|
2559
2559
|
silent: true
|
|
2560
2560
|
});
|
|
2561
|
+
candlesBySymbol[symbol] = candles;
|
|
2562
|
+
candlesRead += candles.length;
|
|
2563
|
+
bar.tick(1, {
|
|
2564
|
+
candles: candlesRead,
|
|
2565
|
+
skip: skippedBreadthChunks,
|
|
2566
|
+
chunk: `${originalChunkIndex + 1}/${chunks.length}`,
|
|
2567
|
+
symbol
|
|
2568
|
+
});
|
|
2569
|
+
}
|
|
2570
|
+
const btcCandles = await connector.kline({
|
|
2571
|
+
symbol: "BTCUSDT",
|
|
2572
|
+
interval: connectorInterval,
|
|
2573
|
+
start: chunk.fetchStartMs,
|
|
2574
|
+
end: chunk.endMs,
|
|
2575
|
+
silent: true
|
|
2576
|
+
});
|
|
2577
|
+
const chunkKey = `${chunk.startMs}:${chunk.endMs}`;
|
|
2578
|
+
for (const plan of plans) {
|
|
2579
|
+
if (!plan.missingChunkKeys.has(chunkKey)) {
|
|
2580
|
+
continue;
|
|
2581
|
+
}
|
|
2582
|
+
const symbolSet = new Set(plan.definition.symbols);
|
|
2583
|
+
const universeCandles = Object.fromEntries(
|
|
2584
|
+
Object.entries(candlesBySymbol).filter(
|
|
2585
|
+
([symbol]) => symbolSet.has(symbol)
|
|
2586
|
+
)
|
|
2587
|
+
);
|
|
2561
2588
|
const rows = buildMarketBreadthRows({
|
|
2562
|
-
universe,
|
|
2589
|
+
universe: plan.definition.universe,
|
|
2563
2590
|
interval: interval2,
|
|
2564
|
-
candlesBySymbol,
|
|
2591
|
+
candlesBySymbol: universeCandles,
|
|
2565
2592
|
btcCandles
|
|
2566
2593
|
}).filter((row) => {
|
|
2567
2594
|
const ts = row.ts.getTime();
|
|
@@ -2570,8 +2597,6 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2570
2597
|
await (0, import_timescale.upsertMarketBreadthRows)(rows);
|
|
2571
2598
|
breadthRows += rows.length;
|
|
2572
2599
|
}
|
|
2573
|
-
} else {
|
|
2574
|
-
console.log(import_chalk.default.gray(`breadth cached: universe=${universe}`));
|
|
2575
2600
|
}
|
|
2576
2601
|
}
|
|
2577
2602
|
console.log(
|
|
@@ -3796,27 +3821,27 @@ var createCoinMarketCapFetchStats = () => ({
|
|
|
3796
3821
|
totalCredits: 0,
|
|
3797
3822
|
byPath: /* @__PURE__ */ new Map()
|
|
3798
3823
|
});
|
|
3799
|
-
var getCoinMarketCapPathLabel = (
|
|
3800
|
-
if (
|
|
3801
|
-
if (
|
|
3802
|
-
if (
|
|
3803
|
-
if (
|
|
3804
|
-
if (
|
|
3805
|
-
if (
|
|
3806
|
-
return
|
|
3807
|
-
};
|
|
3808
|
-
var recordCoinMarketCapFetchStats = (stats,
|
|
3824
|
+
var getCoinMarketCapPathLabel = (path2) => {
|
|
3825
|
+
if (path2.includes("global-metrics")) return "global";
|
|
3826
|
+
if (path2.includes("cryptocurrency/quotes")) return "reference";
|
|
3827
|
+
if (path2.includes("exchange/quotes")) return "exchangeLiquidity";
|
|
3828
|
+
if (path2.includes("fear-and-greed")) return "fearGreed";
|
|
3829
|
+
if (path2.includes("cmc100")) return "cmc100";
|
|
3830
|
+
if (path2.includes("cmc20")) return "cmc20";
|
|
3831
|
+
return path2;
|
|
3832
|
+
};
|
|
3833
|
+
var recordCoinMarketCapFetchStats = (stats, path2, creditCount) => {
|
|
3809
3834
|
if (!stats) return;
|
|
3810
|
-
const existing = stats.byPath.get(
|
|
3835
|
+
const existing = stats.byPath.get(path2) ?? { requests: 0, credits: 0 };
|
|
3811
3836
|
existing.requests += 1;
|
|
3812
3837
|
existing.credits += creditCount ?? 0;
|
|
3813
3838
|
stats.requests += 1;
|
|
3814
3839
|
stats.totalCredits += creditCount ?? 0;
|
|
3815
|
-
stats.byPath.set(
|
|
3840
|
+
stats.byPath.set(path2, existing);
|
|
3816
3841
|
};
|
|
3817
3842
|
var formatCoinMarketCapFetchStats = (stats) => {
|
|
3818
3843
|
const byPath = [...stats.byPath.entries()].map(
|
|
3819
|
-
([
|
|
3844
|
+
([path2, item]) => `${getCoinMarketCapPathLabel(path2)}=${item.requests}req/${item.credits}cr`
|
|
3820
3845
|
).join(" ");
|
|
3821
3846
|
return `apiRequests=${stats.requests} apiCredits=${stats.totalCredits}${byPath ? ` ${byPath}` : ""}`;
|
|
3822
3847
|
};
|
|
@@ -4888,7 +4913,7 @@ var updateBtcReferenceHistory = async ({
|
|
|
4888
4913
|
var import_logger = require("@tradejs/infra/logger");
|
|
4889
4914
|
var import_redis2 = require("@tradejs/infra/redis");
|
|
4890
4915
|
var import_tradingAccounts = require("@tradejs/infra/tradingAccounts");
|
|
4891
|
-
var
|
|
4916
|
+
var import_strategies2 = require("@tradejs/node/strategies");
|
|
4892
4917
|
|
|
4893
4918
|
// src/lib/runtimeRedis.ts
|
|
4894
4919
|
var import_redis = require("@tradejs/infra/redis");
|
|
@@ -4988,7 +5013,7 @@ var loadRuntimeStrategies = async ({
|
|
|
4988
5013
|
});
|
|
4989
5014
|
const effectiveAccountId = resolvedAccount?.id ?? requestedAccountId;
|
|
4990
5015
|
const [strategyCreator, strategyResults] = await Promise.all([
|
|
4991
|
-
(0,
|
|
5016
|
+
(0, import_strategies2.getStrategyCreator)(strategyName, projectRoot2),
|
|
4992
5017
|
(0, import_redis2.getData)(import_redis2.redisKeys.strategyResults(userName, strategyName), {})
|
|
4993
5018
|
]);
|
|
4994
5019
|
if (!strategyCreator) {
|
|
@@ -5082,6 +5107,214 @@ var logStrategySkipStats = (runtimeStrategies, strategyStats) => {
|
|
|
5082
5107
|
|
|
5083
5108
|
// src/lib/signals/evaluations.ts
|
|
5084
5109
|
var import_redis3 = require("@tradejs/infra/redis");
|
|
5110
|
+
|
|
5111
|
+
// src/lib/runtimeLineage.ts
|
|
5112
|
+
var import_node_child_process = require("child_process");
|
|
5113
|
+
var import_node_crypto = require("crypto");
|
|
5114
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
5115
|
+
var import_node_path = __toESM(require("path"));
|
|
5116
|
+
var RUNTIME_CONTEXT_ENV_KEYS = [
|
|
5117
|
+
"AI_MODE",
|
|
5118
|
+
"MIN_AI_QUALITY",
|
|
5119
|
+
"INTERVAL",
|
|
5120
|
+
"DERIVATIVES_CONTEXT_ENABLED",
|
|
5121
|
+
"DERIVATIVES_CONTEXT_TARGET_ENABLED",
|
|
5122
|
+
"DERIVATIVES_CONTEXT_LOOKBACK_HOURS",
|
|
5123
|
+
"DERIVATIVES_CONTEXT_EXTRA_REFERENCE_SYMBOLS",
|
|
5124
|
+
"DERIVATIVES_CONTEXT_EXCHANGE_PRIORITY",
|
|
5125
|
+
"COINMARKETCAP_CONTEXT_ENABLED",
|
|
5126
|
+
"COINMARKETCAP_CONTEXT_MAX_AGE_MS",
|
|
5127
|
+
"COINMARKETCAP_CONTEXT_EXCHANGE_LIQUIDITY_ENABLED",
|
|
5128
|
+
"COINMARKETCAP_CONTEXT_EXCHANGE_SLUGS",
|
|
5129
|
+
"COINMARKETCAP_CONTEXT_FEAR_GREED_ENABLED",
|
|
5130
|
+
"COINMARKETCAP_CONTEXT_HISTORICAL_ACCESS_MONTHS",
|
|
5131
|
+
"COINMARKETCAP_CONTEXT_BACKFILL_ENABLED",
|
|
5132
|
+
"COINMARKETCAP_CONTEXT_BACKFILL_MAX_DAYS",
|
|
5133
|
+
"COINMARKETCAP_CONTEXT_BACKFILL_WARMUP_DAYS"
|
|
5134
|
+
];
|
|
5135
|
+
var RUNTIME_CONTEXT_DATA_MODEL = {
|
|
5136
|
+
derivativesSourceIntervals: "15m",
|
|
5137
|
+
derivativesDerivedIntervals: "1h",
|
|
5138
|
+
derivativesHourlyFallback: "stored-1h",
|
|
5139
|
+
derivativesDataModelVersion: 2,
|
|
5140
|
+
coinMarketCapAvailabilityModel: "closed-interval-all-daily",
|
|
5141
|
+
coinMarketCapDataModelVersion: 3,
|
|
5142
|
+
binanceBreadthUniverseModel: "fixed-versioned-top5-top10-top30-top50-top100",
|
|
5143
|
+
binanceBreadthDataModelVersion: 2
|
|
5144
|
+
};
|
|
5145
|
+
var normalizeForStableJson = (value) => {
|
|
5146
|
+
if (Array.isArray(value)) {
|
|
5147
|
+
return value.map(normalizeForStableJson);
|
|
5148
|
+
}
|
|
5149
|
+
if (value && typeof value === "object") {
|
|
5150
|
+
return Object.fromEntries(
|
|
5151
|
+
Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, entry]) => [key, normalizeForStableJson(entry)])
|
|
5152
|
+
);
|
|
5153
|
+
}
|
|
5154
|
+
return value;
|
|
5155
|
+
};
|
|
5156
|
+
var fingerprintRuntimeValue = (value) => (0, import_node_crypto.createHash)("sha256").update(JSON.stringify(normalizeForStableJson(value))).digest("hex").slice(0, 16);
|
|
5157
|
+
var gitLineageCache = /* @__PURE__ */ new Map();
|
|
5158
|
+
var gateFingerprintCache = /* @__PURE__ */ new Map();
|
|
5159
|
+
var binanceBreadthFingerprintCache = /* @__PURE__ */ new Map();
|
|
5160
|
+
var resolveGitLineage = (projectRoot2) => {
|
|
5161
|
+
const cached = gitLineageCache.get(projectRoot2);
|
|
5162
|
+
if (cached) {
|
|
5163
|
+
return cached;
|
|
5164
|
+
}
|
|
5165
|
+
const envSha = String(process.env.TRADEJS_GIT_SHA ?? "").trim();
|
|
5166
|
+
if (envSha && envSha !== "unknown") {
|
|
5167
|
+
const result = {
|
|
5168
|
+
gitSha: envSha,
|
|
5169
|
+
gitDirty: false
|
|
5170
|
+
};
|
|
5171
|
+
gitLineageCache.set(projectRoot2, result);
|
|
5172
|
+
return result;
|
|
5173
|
+
}
|
|
5174
|
+
try {
|
|
5175
|
+
const gitSha = (0, import_node_child_process.execFileSync)("git", ["rev-parse", "HEAD"], {
|
|
5176
|
+
cwd: projectRoot2,
|
|
5177
|
+
encoding: "utf8",
|
|
5178
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
5179
|
+
}).trim();
|
|
5180
|
+
const status = (0, import_node_child_process.execFileSync)(
|
|
5181
|
+
"git",
|
|
5182
|
+
["status", "--porcelain", "--untracked-files=normal"],
|
|
5183
|
+
{
|
|
5184
|
+
cwd: projectRoot2,
|
|
5185
|
+
encoding: "utf8",
|
|
5186
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
5187
|
+
}
|
|
5188
|
+
).trim();
|
|
5189
|
+
const result = {
|
|
5190
|
+
gitSha: gitSha || null,
|
|
5191
|
+
gitDirty: status.length > 0
|
|
5192
|
+
};
|
|
5193
|
+
gitLineageCache.set(projectRoot2, result);
|
|
5194
|
+
return result;
|
|
5195
|
+
} catch {
|
|
5196
|
+
const result = {
|
|
5197
|
+
gitSha: null,
|
|
5198
|
+
gitDirty: null
|
|
5199
|
+
};
|
|
5200
|
+
gitLineageCache.set(projectRoot2, result);
|
|
5201
|
+
return result;
|
|
5202
|
+
}
|
|
5203
|
+
};
|
|
5204
|
+
var readOptionalFile = async (filePath) => {
|
|
5205
|
+
try {
|
|
5206
|
+
return await import_promises.default.readFile(filePath);
|
|
5207
|
+
} catch {
|
|
5208
|
+
return null;
|
|
5209
|
+
}
|
|
5210
|
+
};
|
|
5211
|
+
var resolveBinanceBreadthFingerprint = async (projectRoot2) => {
|
|
5212
|
+
if (binanceBreadthFingerprintCache.has(projectRoot2)) {
|
|
5213
|
+
return binanceBreadthFingerprintCache.get(projectRoot2) ?? null;
|
|
5214
|
+
}
|
|
5215
|
+
const content = await readOptionalFile(
|
|
5216
|
+
import_node_path.default.join(
|
|
5217
|
+
projectRoot2,
|
|
5218
|
+
"packages/node/src/config/binanceBreadthUniverses.json"
|
|
5219
|
+
)
|
|
5220
|
+
);
|
|
5221
|
+
let result = null;
|
|
5222
|
+
if (content) {
|
|
5223
|
+
try {
|
|
5224
|
+
const parsed = JSON.parse(content.toString("utf8"));
|
|
5225
|
+
result = typeof parsed.fingerprint === "string" && parsed.fingerprint.trim() ? parsed.fingerprint.trim() : null;
|
|
5226
|
+
} catch {
|
|
5227
|
+
result = null;
|
|
5228
|
+
}
|
|
5229
|
+
}
|
|
5230
|
+
binanceBreadthFingerprintCache.set(projectRoot2, result);
|
|
5231
|
+
return result;
|
|
5232
|
+
};
|
|
5233
|
+
var resolveGateFingerprint = async ({
|
|
5234
|
+
projectRoot: projectRoot2,
|
|
5235
|
+
strategyName,
|
|
5236
|
+
gitSha
|
|
5237
|
+
}) => {
|
|
5238
|
+
const cacheKey = `${projectRoot2}:${strategyName}:${gitSha ?? "unknown"}`;
|
|
5239
|
+
const cached = gateFingerprintCache.get(cacheKey);
|
|
5240
|
+
if (cached) {
|
|
5241
|
+
return cached;
|
|
5242
|
+
}
|
|
5243
|
+
const relativeCandidates = [
|
|
5244
|
+
`packages/strategies/src/${strategyName}/adapters/ai.ts`,
|
|
5245
|
+
`packages/strategies/src/${strategyName}/guardrails.ts`,
|
|
5246
|
+
`packages/strategies/src/${strategyName}/pockets.ts`,
|
|
5247
|
+
`packages/strategies/src/${strategyName}/config.ts`,
|
|
5248
|
+
"packages/node/src/ai.ts"
|
|
5249
|
+
];
|
|
5250
|
+
const optionalEntries = await Promise.all(
|
|
5251
|
+
relativeCandidates.map(async (relativePath) => {
|
|
5252
|
+
const content = await readOptionalFile(
|
|
5253
|
+
import_node_path.default.join(projectRoot2, relativePath)
|
|
5254
|
+
);
|
|
5255
|
+
return content == null ? null : { relativePath, content };
|
|
5256
|
+
})
|
|
5257
|
+
);
|
|
5258
|
+
const sourceEntries = [];
|
|
5259
|
+
for (const entry of optionalEntries) {
|
|
5260
|
+
if (entry != null) {
|
|
5261
|
+
sourceEntries.push(entry);
|
|
5262
|
+
}
|
|
5263
|
+
}
|
|
5264
|
+
const hash = (0, import_node_crypto.createHash)("sha256");
|
|
5265
|
+
hash.update(strategyName);
|
|
5266
|
+
if (sourceEntries.length) {
|
|
5267
|
+
for (const entry of sourceEntries) {
|
|
5268
|
+
hash.update(entry.relativePath);
|
|
5269
|
+
hash.update(entry.content);
|
|
5270
|
+
}
|
|
5271
|
+
} else {
|
|
5272
|
+
hash.update(gitSha ?? "unknown-git-sha");
|
|
5273
|
+
}
|
|
5274
|
+
const fingerprint = hash.digest("hex").slice(0, 16);
|
|
5275
|
+
gateFingerprintCache.set(cacheKey, fingerprint);
|
|
5276
|
+
return fingerprint;
|
|
5277
|
+
};
|
|
5278
|
+
var buildRuntimeLineage = async ({
|
|
5279
|
+
projectRoot: projectRoot2,
|
|
5280
|
+
strategyName,
|
|
5281
|
+
config,
|
|
5282
|
+
runContext,
|
|
5283
|
+
env = process.env
|
|
5284
|
+
}) => {
|
|
5285
|
+
const git = resolveGitLineage(projectRoot2);
|
|
5286
|
+
const context = {
|
|
5287
|
+
...Object.fromEntries(
|
|
5288
|
+
RUNTIME_CONTEXT_ENV_KEYS.map((key) => [key, env[key] ?? null])
|
|
5289
|
+
),
|
|
5290
|
+
...RUNTIME_CONTEXT_DATA_MODEL,
|
|
5291
|
+
binanceBreadthUniverseFingerprint: await resolveBinanceBreadthFingerprint(projectRoot2),
|
|
5292
|
+
...runContext
|
|
5293
|
+
};
|
|
5294
|
+
return {
|
|
5295
|
+
schemaVersion: 1,
|
|
5296
|
+
...git,
|
|
5297
|
+
gateFingerprint: await resolveGateFingerprint({
|
|
5298
|
+
projectRoot: projectRoot2,
|
|
5299
|
+
strategyName,
|
|
5300
|
+
gitSha: git.gitSha
|
|
5301
|
+
}),
|
|
5302
|
+
configFingerprint: fingerprintRuntimeValue(config),
|
|
5303
|
+
contextFingerprint: fingerprintRuntimeValue(context)
|
|
5304
|
+
};
|
|
5305
|
+
};
|
|
5306
|
+
var runtimeLineageKey = (lineage) => [
|
|
5307
|
+
lineage.schemaVersion,
|
|
5308
|
+
lineage.gitSha ?? "unknown",
|
|
5309
|
+
lineage.gitDirty == null ? "unknown" : lineage.gitDirty ? "dirty" : "clean",
|
|
5310
|
+
lineage.gateFingerprint,
|
|
5311
|
+
lineage.configFingerprint,
|
|
5312
|
+
lineage.contextFingerprint
|
|
5313
|
+
].join(":");
|
|
5314
|
+
|
|
5315
|
+
// src/lib/signals/evaluations.ts
|
|
5316
|
+
var runtimeLineageScopeCache = /* @__PURE__ */ new Map();
|
|
5317
|
+
var runtimeLineageScopeCacheDayKey = "";
|
|
5085
5318
|
var buildRuntimeSignalEvaluationId = ({
|
|
5086
5319
|
strategyName,
|
|
5087
5320
|
symbol,
|
|
@@ -5090,7 +5323,46 @@ var buildRuntimeSignalEvaluationId = ({
|
|
|
5090
5323
|
}) => runtimeConfigId && runtimeConfigId !== "config" ? [strategyName, runtimeConfigId, symbol, timestamp].join(":") : [strategyName, symbol, timestamp].join(":");
|
|
5091
5324
|
var saveRuntimeSignalEvaluation = async (evaluation) => {
|
|
5092
5325
|
const dayKey = (0, import_time.getRuntimeStorageDayKey)(evaluation.timestamp);
|
|
5326
|
+
if (runtimeLineageScopeCacheDayKey !== dayKey) {
|
|
5327
|
+
runtimeLineageScopeCache.clear();
|
|
5328
|
+
runtimeLineageScopeCacheDayKey = dayKey;
|
|
5329
|
+
}
|
|
5093
5330
|
const runtimeSignalRetentionTtl = getRuntimeSignalRetentionTtlSeconds();
|
|
5331
|
+
if (evaluation.runtimeLineage) {
|
|
5332
|
+
const lineageField = [
|
|
5333
|
+
evaluation.strategy,
|
|
5334
|
+
evaluation.runtimeConfigId ?? "config",
|
|
5335
|
+
evaluation.symbol,
|
|
5336
|
+
runtimeLineageKey(evaluation.runtimeLineage)
|
|
5337
|
+
].join(":");
|
|
5338
|
+
const lineageBucket = import_redis3.redisKeys.runtimeLineageScopeBucket(
|
|
5339
|
+
evaluation.userName,
|
|
5340
|
+
dayKey
|
|
5341
|
+
);
|
|
5342
|
+
const cacheKey = `${lineageBucket}:${lineageField}`;
|
|
5343
|
+
const existing = runtimeLineageScopeCache.get(cacheKey) ?? await (0, import_redis3.getHashJsonField)(
|
|
5344
|
+
lineageBucket,
|
|
5345
|
+
lineageField
|
|
5346
|
+
);
|
|
5347
|
+
const scope = {
|
|
5348
|
+
strategy: evaluation.strategy,
|
|
5349
|
+
symbol: evaluation.symbol,
|
|
5350
|
+
runtimeConfigId: evaluation.runtimeConfigId,
|
|
5351
|
+
lineage: evaluation.runtimeLineage,
|
|
5352
|
+
firstTimestamp: Math.min(
|
|
5353
|
+
existing?.firstTimestamp ?? evaluation.timestamp,
|
|
5354
|
+
evaluation.timestamp
|
|
5355
|
+
),
|
|
5356
|
+
lastTimestamp: Math.max(
|
|
5357
|
+
existing?.lastTimestamp ?? evaluation.timestamp,
|
|
5358
|
+
evaluation.timestamp
|
|
5359
|
+
)
|
|
5360
|
+
};
|
|
5361
|
+
runtimeLineageScopeCache.set(cacheKey, scope);
|
|
5362
|
+
await (0, import_redis3.setHashJsonField)(lineageBucket, lineageField, scope, {
|
|
5363
|
+
expire: RUNTIME_LINEAGE_SCOPE_RETENTION_TTL_SECONDS
|
|
5364
|
+
});
|
|
5365
|
+
}
|
|
5094
5366
|
if (shouldStoreDetailedRuntimeSignalEvaluation(evaluation)) {
|
|
5095
5367
|
await (0, import_redis3.setHashJsonField)(
|
|
5096
5368
|
import_redis3.redisKeys.runtimeSignalEvaluationBucket(
|
|
@@ -5550,7 +5822,7 @@ var resolveSignalsKlineWsWaitMs = () => resolveNonNegativeInteger(process.env.SI
|
|
|
5550
5822
|
var createDefaultSignalsLifecycle = (runtimeInterval = interval) => createSignalsStrategyLifecycle({
|
|
5551
5823
|
intervalMs: Number(runtimeInterval) * 6e4,
|
|
5552
5824
|
maxLiveBars: resolveSignalsDaemonMaxLiveBars(runtimeInterval),
|
|
5553
|
-
releaseState:
|
|
5825
|
+
releaseState: import_strategies3.releaseStrategyReplayCache
|
|
5554
5826
|
});
|
|
5555
5827
|
var timeOperation2 = (label, operation) => timeOperation(
|
|
5556
5828
|
label,
|
|
@@ -5695,6 +5967,20 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
5695
5967
|
interval: interval2,
|
|
5696
5968
|
makeOrders: flags.makeOrders
|
|
5697
5969
|
});
|
|
5970
|
+
const runtimeLineage = await buildRuntimeLineage({
|
|
5971
|
+
projectRoot,
|
|
5972
|
+
strategyName,
|
|
5973
|
+
config: {
|
|
5974
|
+
configId,
|
|
5975
|
+
strategyConfig,
|
|
5976
|
+
symbolResultConfig: strategyResults?.[symbol]?.config ?? null
|
|
5977
|
+
},
|
|
5978
|
+
runContext: {
|
|
5979
|
+
connectorName: connectorName.toLowerCase(),
|
|
5980
|
+
interval: String(interval2),
|
|
5981
|
+
universe
|
|
5982
|
+
}
|
|
5983
|
+
});
|
|
5698
5984
|
const lifecycleKey = buildSignalsStrategyLifecycleKey({
|
|
5699
5985
|
connectorName,
|
|
5700
5986
|
universe: runtimeScopeUniverse,
|
|
@@ -5776,6 +6062,7 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
5776
6062
|
userName: flags.user,
|
|
5777
6063
|
strategy: strategyName,
|
|
5778
6064
|
runtimeConfigId: configId,
|
|
6065
|
+
runtimeLineage,
|
|
5779
6066
|
symbol,
|
|
5780
6067
|
interval: interval2,
|
|
5781
6068
|
universe,
|
|
@@ -5794,10 +6081,11 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
5794
6081
|
stats.signals += 1;
|
|
5795
6082
|
}
|
|
5796
6083
|
signal.runtimeConfigId = configId;
|
|
6084
|
+
signal.runtimeLineage = runtimeLineage;
|
|
5797
6085
|
if (configId && configId !== "config" && !signal.signalId.endsWith(`:${configId}`)) {
|
|
5798
6086
|
signal.signalId = `${signal.signalId}:${configId}`;
|
|
5799
6087
|
}
|
|
5800
|
-
await (0,
|
|
6088
|
+
await (0, import_strategies4.enrichSignalWithBinanceMarketContext)({
|
|
5801
6089
|
signal,
|
|
5802
6090
|
env: "CRON"
|
|
5803
6091
|
});
|
|
@@ -5840,6 +6128,7 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
5840
6128
|
userName: flags.user,
|
|
5841
6129
|
strategy: strategyName,
|
|
5842
6130
|
runtimeConfigId: configId,
|
|
6131
|
+
runtimeLineage,
|
|
5843
6132
|
symbol,
|
|
5844
6133
|
interval: interval2,
|
|
5845
6134
|
universe,
|