@tradejs/cli 2.0.18 → 2.0.19
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 +12810 -19565
- package/dist/lib/aiExport.js +1 -1607
- package/dist/lib/binanceMarketContextBackfill.js +7 -6
- package/dist/lib/coinMarketCapContextBackfill.js +19 -18
- package/dist/lib/derivativesContextBackfill.js +10 -9
- package/dist/lib/hyperliquidWhaleBackfill.js +8 -8
- package/dist/lib/hyperliquidWhaleStream.js +4 -4
- package/dist/lib/marketContextPrepare.js +83 -1686
- package/dist/lib/runEnvironment.js +14 -1666
- package/dist/lib/runFormatting.js +1 -1607
- package/dist/lib/runtimeDebugEvidence.js +2 -48
- package/dist/lib/runtimeRedis.js +6 -57
- package/dist/lib/runtimeStrategyBacktest.js +2 -48
- package/dist/scripts/aiExport.js +1 -1607
- package/dist/scripts/aiPocketSearch.js +1 -1607
- package/dist/scripts/aiTrain.js +17 -1623
- package/dist/scripts/backtest.js +110 -1759
- package/dist/scripts/binanceMarketIngest.js +5 -4
- package/dist/scripts/candlesMigrateProvider.js +6 -5186
- package/dist/scripts/cleanupMarketContext.js +4 -3
- package/dist/scripts/continuity.js +4 -3
- package/dist/scripts/derivativesIngest.js +6 -4
- package/dist/scripts/derivativesIngestCoinalyzeAll.js +5 -4
- package/dist/scripts/doctor.js +2 -5184
- package/dist/scripts/hyperliquidWhaleBackfill.js +8 -8
- package/dist/scripts/hyperliquidWhaleIngest.js +4 -4
- package/dist/scripts/hyperliquidWhalesUpdate.js +1 -1
- package/dist/scripts/migration.js +3 -3
- package/dist/scripts/mlExport.js +1 -1607
- package/dist/scripts/replay.js +133 -1782
- package/dist/scripts/replayRunner.js +133 -1782
- package/dist/scripts/replayRuntimeEvidence.js +2 -48
- package/dist/scripts/researchAuto.js +3 -49
- package/dist/scripts/results.js +1 -1607
- package/dist/scripts/runtimeEvidence.js +2 -48
- package/dist/scripts/runtimeParity.js +121 -1746
- package/dist/scripts/signals.js +1057 -2647
- package/dist/scripts/signalsDaemon.js +1051 -2608
- package/dist/scripts/signalsSummary.js +4 -26
- package/dist/workers/testerWorker.js +2 -2
- package/package.json +11 -9
package/dist/scripts/signals.js
CHANGED
|
@@ -5,13 +5,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __commonJS = (cb, mod) => function __require() {
|
|
9
|
-
try {
|
|
10
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
11
|
-
} catch (e) {
|
|
12
|
-
throw mod = 0, e;
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
8
|
var __export = (target, all) => {
|
|
16
9
|
for (var name in all)
|
|
17
10
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -34,1605 +27,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
34
27
|
));
|
|
35
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
36
29
|
|
|
37
|
-
// ../../node_modules/ms/index.js
|
|
38
|
-
var require_ms = __commonJS({
|
|
39
|
-
"../../node_modules/ms/index.js"(exports2, module2) {
|
|
40
|
-
"use strict";
|
|
41
|
-
var s = 1e3;
|
|
42
|
-
var m = s * 60;
|
|
43
|
-
var h = m * 60;
|
|
44
|
-
var d = h * 24;
|
|
45
|
-
var w = d * 7;
|
|
46
|
-
var y = d * 365.25;
|
|
47
|
-
module2.exports = function(val, options) {
|
|
48
|
-
options = options || {};
|
|
49
|
-
var type = typeof val;
|
|
50
|
-
if (type === "string" && val.length > 0) {
|
|
51
|
-
return parse(val);
|
|
52
|
-
} else if (type === "number" && isFinite(val)) {
|
|
53
|
-
return options.long ? fmtLong(val) : fmtShort(val);
|
|
54
|
-
}
|
|
55
|
-
throw new Error(
|
|
56
|
-
"val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
|
|
57
|
-
);
|
|
58
|
-
};
|
|
59
|
-
function parse(str) {
|
|
60
|
-
str = String(str);
|
|
61
|
-
if (str.length > 100) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
|
|
65
|
-
str
|
|
66
|
-
);
|
|
67
|
-
if (!match) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
var n = parseFloat(match[1]);
|
|
71
|
-
var type = (match[2] || "ms").toLowerCase();
|
|
72
|
-
switch (type) {
|
|
73
|
-
case "years":
|
|
74
|
-
case "year":
|
|
75
|
-
case "yrs":
|
|
76
|
-
case "yr":
|
|
77
|
-
case "y":
|
|
78
|
-
return n * y;
|
|
79
|
-
case "weeks":
|
|
80
|
-
case "week":
|
|
81
|
-
case "w":
|
|
82
|
-
return n * w;
|
|
83
|
-
case "days":
|
|
84
|
-
case "day":
|
|
85
|
-
case "d":
|
|
86
|
-
return n * d;
|
|
87
|
-
case "hours":
|
|
88
|
-
case "hour":
|
|
89
|
-
case "hrs":
|
|
90
|
-
case "hr":
|
|
91
|
-
case "h":
|
|
92
|
-
return n * h;
|
|
93
|
-
case "minutes":
|
|
94
|
-
case "minute":
|
|
95
|
-
case "mins":
|
|
96
|
-
case "min":
|
|
97
|
-
case "m":
|
|
98
|
-
return n * m;
|
|
99
|
-
case "seconds":
|
|
100
|
-
case "second":
|
|
101
|
-
case "secs":
|
|
102
|
-
case "sec":
|
|
103
|
-
case "s":
|
|
104
|
-
return n * s;
|
|
105
|
-
case "milliseconds":
|
|
106
|
-
case "millisecond":
|
|
107
|
-
case "msecs":
|
|
108
|
-
case "msec":
|
|
109
|
-
case "ms":
|
|
110
|
-
return n;
|
|
111
|
-
default:
|
|
112
|
-
return void 0;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
function fmtShort(ms) {
|
|
116
|
-
var msAbs = Math.abs(ms);
|
|
117
|
-
if (msAbs >= d) {
|
|
118
|
-
return Math.round(ms / d) + "d";
|
|
119
|
-
}
|
|
120
|
-
if (msAbs >= h) {
|
|
121
|
-
return Math.round(ms / h) + "h";
|
|
122
|
-
}
|
|
123
|
-
if (msAbs >= m) {
|
|
124
|
-
return Math.round(ms / m) + "m";
|
|
125
|
-
}
|
|
126
|
-
if (msAbs >= s) {
|
|
127
|
-
return Math.round(ms / s) + "s";
|
|
128
|
-
}
|
|
129
|
-
return ms + "ms";
|
|
130
|
-
}
|
|
131
|
-
function fmtLong(ms) {
|
|
132
|
-
var msAbs = Math.abs(ms);
|
|
133
|
-
if (msAbs >= d) {
|
|
134
|
-
return plural(ms, msAbs, d, "day");
|
|
135
|
-
}
|
|
136
|
-
if (msAbs >= h) {
|
|
137
|
-
return plural(ms, msAbs, h, "hour");
|
|
138
|
-
}
|
|
139
|
-
if (msAbs >= m) {
|
|
140
|
-
return plural(ms, msAbs, m, "minute");
|
|
141
|
-
}
|
|
142
|
-
if (msAbs >= s) {
|
|
143
|
-
return plural(ms, msAbs, s, "second");
|
|
144
|
-
}
|
|
145
|
-
return ms + " ms";
|
|
146
|
-
}
|
|
147
|
-
function plural(ms, msAbs, n, name) {
|
|
148
|
-
var isPlural = msAbs >= n * 1.5;
|
|
149
|
-
return Math.round(ms / n) + " " + name + (isPlural ? "s" : "");
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
// ../../node_modules/list-it/node_modules/debug/src/common.js
|
|
155
|
-
var require_common = __commonJS({
|
|
156
|
-
"../../node_modules/list-it/node_modules/debug/src/common.js"(exports2, module2) {
|
|
157
|
-
"use strict";
|
|
158
|
-
function setup(env) {
|
|
159
|
-
createDebug.debug = createDebug;
|
|
160
|
-
createDebug.default = createDebug;
|
|
161
|
-
createDebug.coerce = coerce;
|
|
162
|
-
createDebug.disable = disable;
|
|
163
|
-
createDebug.enable = enable;
|
|
164
|
-
createDebug.enabled = enabled;
|
|
165
|
-
createDebug.humanize = require_ms();
|
|
166
|
-
createDebug.destroy = destroy;
|
|
167
|
-
Object.keys(env).forEach((key) => {
|
|
168
|
-
createDebug[key] = env[key];
|
|
169
|
-
});
|
|
170
|
-
createDebug.names = [];
|
|
171
|
-
createDebug.skips = [];
|
|
172
|
-
createDebug.formatters = {};
|
|
173
|
-
function selectColor(namespace) {
|
|
174
|
-
let hash = 0;
|
|
175
|
-
for (let i = 0; i < namespace.length; i++) {
|
|
176
|
-
hash = (hash << 5) - hash + namespace.charCodeAt(i);
|
|
177
|
-
hash |= 0;
|
|
178
|
-
}
|
|
179
|
-
return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
|
|
180
|
-
}
|
|
181
|
-
createDebug.selectColor = selectColor;
|
|
182
|
-
function createDebug(namespace) {
|
|
183
|
-
let prevTime;
|
|
184
|
-
let enableOverride = null;
|
|
185
|
-
let namespacesCache;
|
|
186
|
-
let enabledCache;
|
|
187
|
-
function debug(...args2) {
|
|
188
|
-
if (!debug.enabled) {
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
const self = debug;
|
|
192
|
-
const curr = Number(/* @__PURE__ */ new Date());
|
|
193
|
-
const ms = curr - (prevTime || curr);
|
|
194
|
-
self.diff = ms;
|
|
195
|
-
self.prev = prevTime;
|
|
196
|
-
self.curr = curr;
|
|
197
|
-
prevTime = curr;
|
|
198
|
-
args2[0] = createDebug.coerce(args2[0]);
|
|
199
|
-
if (typeof args2[0] !== "string") {
|
|
200
|
-
args2.unshift("%O");
|
|
201
|
-
}
|
|
202
|
-
let index = 0;
|
|
203
|
-
args2[0] = args2[0].replace(/%([a-zA-Z%])/g, (match, format2) => {
|
|
204
|
-
if (match === "%%") {
|
|
205
|
-
return "%";
|
|
206
|
-
}
|
|
207
|
-
index++;
|
|
208
|
-
const formatter = createDebug.formatters[format2];
|
|
209
|
-
if (typeof formatter === "function") {
|
|
210
|
-
const val = args2[index];
|
|
211
|
-
match = formatter.call(self, val);
|
|
212
|
-
args2.splice(index, 1);
|
|
213
|
-
index--;
|
|
214
|
-
}
|
|
215
|
-
return match;
|
|
216
|
-
});
|
|
217
|
-
createDebug.formatArgs.call(self, args2);
|
|
218
|
-
const logFn = self.log || createDebug.log;
|
|
219
|
-
logFn.apply(self, args2);
|
|
220
|
-
}
|
|
221
|
-
debug.namespace = namespace;
|
|
222
|
-
debug.useColors = createDebug.useColors();
|
|
223
|
-
debug.color = createDebug.selectColor(namespace);
|
|
224
|
-
debug.extend = extend;
|
|
225
|
-
debug.destroy = createDebug.destroy;
|
|
226
|
-
Object.defineProperty(debug, "enabled", {
|
|
227
|
-
enumerable: true,
|
|
228
|
-
configurable: false,
|
|
229
|
-
get: () => {
|
|
230
|
-
if (enableOverride !== null) {
|
|
231
|
-
return enableOverride;
|
|
232
|
-
}
|
|
233
|
-
if (namespacesCache !== createDebug.namespaces) {
|
|
234
|
-
namespacesCache = createDebug.namespaces;
|
|
235
|
-
enabledCache = createDebug.enabled(namespace);
|
|
236
|
-
}
|
|
237
|
-
return enabledCache;
|
|
238
|
-
},
|
|
239
|
-
set: (v) => {
|
|
240
|
-
enableOverride = v;
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
if (typeof createDebug.init === "function") {
|
|
244
|
-
createDebug.init(debug);
|
|
245
|
-
}
|
|
246
|
-
return debug;
|
|
247
|
-
}
|
|
248
|
-
function extend(namespace, delimiter) {
|
|
249
|
-
const newDebug = createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace);
|
|
250
|
-
newDebug.log = this.log;
|
|
251
|
-
return newDebug;
|
|
252
|
-
}
|
|
253
|
-
function enable(namespaces) {
|
|
254
|
-
createDebug.save(namespaces);
|
|
255
|
-
createDebug.namespaces = namespaces;
|
|
256
|
-
createDebug.names = [];
|
|
257
|
-
createDebug.skips = [];
|
|
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
|
-
}
|
|
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;
|
|
286
|
-
} else {
|
|
287
|
-
return false;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
while (templateIndex < template.length && template[templateIndex] === "*") {
|
|
291
|
-
templateIndex++;
|
|
292
|
-
}
|
|
293
|
-
return templateIndex === template.length;
|
|
294
|
-
}
|
|
295
|
-
function disable() {
|
|
296
|
-
const namespaces = [
|
|
297
|
-
...createDebug.names,
|
|
298
|
-
...createDebug.skips.map((namespace) => "-" + namespace)
|
|
299
|
-
].join(",");
|
|
300
|
-
createDebug.enable("");
|
|
301
|
-
return namespaces;
|
|
302
|
-
}
|
|
303
|
-
function enabled(name) {
|
|
304
|
-
for (const skip of createDebug.skips) {
|
|
305
|
-
if (matchesTemplate(name, skip)) {
|
|
306
|
-
return false;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
for (const ns of createDebug.names) {
|
|
310
|
-
if (matchesTemplate(name, ns)) {
|
|
311
|
-
return true;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
return false;
|
|
315
|
-
}
|
|
316
|
-
function coerce(val) {
|
|
317
|
-
if (val instanceof Error) {
|
|
318
|
-
return val.stack || val.message;
|
|
319
|
-
}
|
|
320
|
-
return val;
|
|
321
|
-
}
|
|
322
|
-
function destroy() {
|
|
323
|
-
console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
|
|
324
|
-
}
|
|
325
|
-
createDebug.enable(createDebug.load());
|
|
326
|
-
return createDebug;
|
|
327
|
-
}
|
|
328
|
-
module2.exports = setup;
|
|
329
|
-
}
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
// ../../node_modules/list-it/node_modules/debug/src/browser.js
|
|
333
|
-
var require_browser = __commonJS({
|
|
334
|
-
"../../node_modules/list-it/node_modules/debug/src/browser.js"(exports2, module2) {
|
|
335
|
-
"use strict";
|
|
336
|
-
exports2.formatArgs = formatArgs;
|
|
337
|
-
exports2.save = save;
|
|
338
|
-
exports2.load = load;
|
|
339
|
-
exports2.useColors = useColors;
|
|
340
|
-
exports2.storage = localstorage();
|
|
341
|
-
exports2.destroy = /* @__PURE__ */ (() => {
|
|
342
|
-
let warned = false;
|
|
343
|
-
return () => {
|
|
344
|
-
if (!warned) {
|
|
345
|
-
warned = true;
|
|
346
|
-
console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
|
|
347
|
-
}
|
|
348
|
-
};
|
|
349
|
-
})();
|
|
350
|
-
exports2.colors = [
|
|
351
|
-
"#0000CC",
|
|
352
|
-
"#0000FF",
|
|
353
|
-
"#0033CC",
|
|
354
|
-
"#0033FF",
|
|
355
|
-
"#0066CC",
|
|
356
|
-
"#0066FF",
|
|
357
|
-
"#0099CC",
|
|
358
|
-
"#0099FF",
|
|
359
|
-
"#00CC00",
|
|
360
|
-
"#00CC33",
|
|
361
|
-
"#00CC66",
|
|
362
|
-
"#00CC99",
|
|
363
|
-
"#00CCCC",
|
|
364
|
-
"#00CCFF",
|
|
365
|
-
"#3300CC",
|
|
366
|
-
"#3300FF",
|
|
367
|
-
"#3333CC",
|
|
368
|
-
"#3333FF",
|
|
369
|
-
"#3366CC",
|
|
370
|
-
"#3366FF",
|
|
371
|
-
"#3399CC",
|
|
372
|
-
"#3399FF",
|
|
373
|
-
"#33CC00",
|
|
374
|
-
"#33CC33",
|
|
375
|
-
"#33CC66",
|
|
376
|
-
"#33CC99",
|
|
377
|
-
"#33CCCC",
|
|
378
|
-
"#33CCFF",
|
|
379
|
-
"#6600CC",
|
|
380
|
-
"#6600FF",
|
|
381
|
-
"#6633CC",
|
|
382
|
-
"#6633FF",
|
|
383
|
-
"#66CC00",
|
|
384
|
-
"#66CC33",
|
|
385
|
-
"#9900CC",
|
|
386
|
-
"#9900FF",
|
|
387
|
-
"#9933CC",
|
|
388
|
-
"#9933FF",
|
|
389
|
-
"#99CC00",
|
|
390
|
-
"#99CC33",
|
|
391
|
-
"#CC0000",
|
|
392
|
-
"#CC0033",
|
|
393
|
-
"#CC0066",
|
|
394
|
-
"#CC0099",
|
|
395
|
-
"#CC00CC",
|
|
396
|
-
"#CC00FF",
|
|
397
|
-
"#CC3300",
|
|
398
|
-
"#CC3333",
|
|
399
|
-
"#CC3366",
|
|
400
|
-
"#CC3399",
|
|
401
|
-
"#CC33CC",
|
|
402
|
-
"#CC33FF",
|
|
403
|
-
"#CC6600",
|
|
404
|
-
"#CC6633",
|
|
405
|
-
"#CC9900",
|
|
406
|
-
"#CC9933",
|
|
407
|
-
"#CCCC00",
|
|
408
|
-
"#CCCC33",
|
|
409
|
-
"#FF0000",
|
|
410
|
-
"#FF0033",
|
|
411
|
-
"#FF0066",
|
|
412
|
-
"#FF0099",
|
|
413
|
-
"#FF00CC",
|
|
414
|
-
"#FF00FF",
|
|
415
|
-
"#FF3300",
|
|
416
|
-
"#FF3333",
|
|
417
|
-
"#FF3366",
|
|
418
|
-
"#FF3399",
|
|
419
|
-
"#FF33CC",
|
|
420
|
-
"#FF33FF",
|
|
421
|
-
"#FF6600",
|
|
422
|
-
"#FF6633",
|
|
423
|
-
"#FF9900",
|
|
424
|
-
"#FF9933",
|
|
425
|
-
"#FFCC00",
|
|
426
|
-
"#FFCC33"
|
|
427
|
-
];
|
|
428
|
-
function useColors() {
|
|
429
|
-
if (typeof window !== "undefined" && window.process && (window.process.type === "renderer" || window.process.__nwjs)) {
|
|
430
|
-
return true;
|
|
431
|
-
}
|
|
432
|
-
if (typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
|
|
433
|
-
return false;
|
|
434
|
-
}
|
|
435
|
-
let m;
|
|
436
|
-
return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773
|
|
437
|
-
typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?
|
|
438
|
-
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
|
|
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
|
|
440
|
-
typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
|
|
441
|
-
}
|
|
442
|
-
function formatArgs(args2) {
|
|
443
|
-
args2[0] = (this.useColors ? "%c" : "") + this.namespace + (this.useColors ? " %c" : " ") + args2[0] + (this.useColors ? "%c " : " ") + "+" + module2.exports.humanize(this.diff);
|
|
444
|
-
if (!this.useColors) {
|
|
445
|
-
return;
|
|
446
|
-
}
|
|
447
|
-
const c = "color: " + this.color;
|
|
448
|
-
args2.splice(1, 0, c, "color: inherit");
|
|
449
|
-
let index = 0;
|
|
450
|
-
let lastC = 0;
|
|
451
|
-
args2[0].replace(/%[a-zA-Z%]/g, (match) => {
|
|
452
|
-
if (match === "%%") {
|
|
453
|
-
return;
|
|
454
|
-
}
|
|
455
|
-
index++;
|
|
456
|
-
if (match === "%c") {
|
|
457
|
-
lastC = index;
|
|
458
|
-
}
|
|
459
|
-
});
|
|
460
|
-
args2.splice(lastC, 0, c);
|
|
461
|
-
}
|
|
462
|
-
exports2.log = console.debug || console.log || (() => {
|
|
463
|
-
});
|
|
464
|
-
function save(namespaces) {
|
|
465
|
-
try {
|
|
466
|
-
if (namespaces) {
|
|
467
|
-
exports2.storage.setItem("debug", namespaces);
|
|
468
|
-
} else {
|
|
469
|
-
exports2.storage.removeItem("debug");
|
|
470
|
-
}
|
|
471
|
-
} catch (error) {
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
function load() {
|
|
475
|
-
let r;
|
|
476
|
-
try {
|
|
477
|
-
r = exports2.storage.getItem("debug") || exports2.storage.getItem("DEBUG");
|
|
478
|
-
} catch (error) {
|
|
479
|
-
}
|
|
480
|
-
if (!r && typeof process !== "undefined" && "env" in process) {
|
|
481
|
-
r = process.env.DEBUG;
|
|
482
|
-
}
|
|
483
|
-
return r;
|
|
484
|
-
}
|
|
485
|
-
function localstorage() {
|
|
486
|
-
try {
|
|
487
|
-
return localStorage;
|
|
488
|
-
} catch (error) {
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
module2.exports = require_common()(exports2);
|
|
492
|
-
var { formatters } = module2.exports;
|
|
493
|
-
formatters.j = function(v) {
|
|
494
|
-
try {
|
|
495
|
-
return JSON.stringify(v);
|
|
496
|
-
} catch (error) {
|
|
497
|
-
return "[UnexpectedJSONParseError]: " + error.message;
|
|
498
|
-
}
|
|
499
|
-
};
|
|
500
|
-
}
|
|
501
|
-
});
|
|
502
|
-
|
|
503
|
-
// ../../node_modules/has-flag/index.js
|
|
504
|
-
var require_has_flag = __commonJS({
|
|
505
|
-
"../../node_modules/has-flag/index.js"(exports2, module2) {
|
|
506
|
-
"use strict";
|
|
507
|
-
module2.exports = (flag, argv = process.argv) => {
|
|
508
|
-
const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
509
|
-
const position = argv.indexOf(prefix + flag);
|
|
510
|
-
const terminatorPosition = argv.indexOf("--");
|
|
511
|
-
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
512
|
-
};
|
|
513
|
-
}
|
|
514
|
-
});
|
|
515
|
-
|
|
516
|
-
// ../../node_modules/supports-color/index.js
|
|
517
|
-
var require_supports_color = __commonJS({
|
|
518
|
-
"../../node_modules/supports-color/index.js"(exports2, module2) {
|
|
519
|
-
"use strict";
|
|
520
|
-
var os = require("os");
|
|
521
|
-
var tty = require("tty");
|
|
522
|
-
var hasFlag = require_has_flag();
|
|
523
|
-
var { env } = process;
|
|
524
|
-
var forceColor;
|
|
525
|
-
if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
|
|
526
|
-
forceColor = 0;
|
|
527
|
-
} else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
|
|
528
|
-
forceColor = 1;
|
|
529
|
-
}
|
|
530
|
-
if ("FORCE_COLOR" in env) {
|
|
531
|
-
if (env.FORCE_COLOR === "true") {
|
|
532
|
-
forceColor = 1;
|
|
533
|
-
} else if (env.FORCE_COLOR === "false") {
|
|
534
|
-
forceColor = 0;
|
|
535
|
-
} else {
|
|
536
|
-
forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
function translateLevel(level) {
|
|
540
|
-
if (level === 0) {
|
|
541
|
-
return false;
|
|
542
|
-
}
|
|
543
|
-
return {
|
|
544
|
-
level,
|
|
545
|
-
hasBasic: true,
|
|
546
|
-
has256: level >= 2,
|
|
547
|
-
has16m: level >= 3
|
|
548
|
-
};
|
|
549
|
-
}
|
|
550
|
-
function supportsColor(haveStream, streamIsTTY) {
|
|
551
|
-
if (forceColor === 0) {
|
|
552
|
-
return 0;
|
|
553
|
-
}
|
|
554
|
-
if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
|
|
555
|
-
return 3;
|
|
556
|
-
}
|
|
557
|
-
if (hasFlag("color=256")) {
|
|
558
|
-
return 2;
|
|
559
|
-
}
|
|
560
|
-
if (haveStream && !streamIsTTY && forceColor === void 0) {
|
|
561
|
-
return 0;
|
|
562
|
-
}
|
|
563
|
-
const min = forceColor || 0;
|
|
564
|
-
if (env.TERM === "dumb") {
|
|
565
|
-
return min;
|
|
566
|
-
}
|
|
567
|
-
if (process.platform === "win32") {
|
|
568
|
-
const osRelease = os.release().split(".");
|
|
569
|
-
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
570
|
-
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
571
|
-
}
|
|
572
|
-
return 1;
|
|
573
|
-
}
|
|
574
|
-
if ("CI" in env) {
|
|
575
|
-
if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
|
|
576
|
-
return 1;
|
|
577
|
-
}
|
|
578
|
-
return min;
|
|
579
|
-
}
|
|
580
|
-
if ("TEAMCITY_VERSION" in env) {
|
|
581
|
-
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
|
582
|
-
}
|
|
583
|
-
if (env.COLORTERM === "truecolor") {
|
|
584
|
-
return 3;
|
|
585
|
-
}
|
|
586
|
-
if ("TERM_PROGRAM" in env) {
|
|
587
|
-
const version = parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
|
|
588
|
-
switch (env.TERM_PROGRAM) {
|
|
589
|
-
case "iTerm.app":
|
|
590
|
-
return version >= 3 ? 3 : 2;
|
|
591
|
-
case "Apple_Terminal":
|
|
592
|
-
return 2;
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
if (/-256(color)?$/i.test(env.TERM)) {
|
|
596
|
-
return 2;
|
|
597
|
-
}
|
|
598
|
-
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
599
|
-
return 1;
|
|
600
|
-
}
|
|
601
|
-
if ("COLORTERM" in env) {
|
|
602
|
-
return 1;
|
|
603
|
-
}
|
|
604
|
-
return min;
|
|
605
|
-
}
|
|
606
|
-
function getSupportLevel(stream) {
|
|
607
|
-
const level = supportsColor(stream, stream && stream.isTTY);
|
|
608
|
-
return translateLevel(level);
|
|
609
|
-
}
|
|
610
|
-
module2.exports = {
|
|
611
|
-
supportsColor: getSupportLevel,
|
|
612
|
-
stdout: translateLevel(supportsColor(true, tty.isatty(1))),
|
|
613
|
-
stderr: translateLevel(supportsColor(true, tty.isatty(2)))
|
|
614
|
-
};
|
|
615
|
-
}
|
|
616
|
-
});
|
|
617
|
-
|
|
618
|
-
// ../../node_modules/list-it/node_modules/debug/src/node.js
|
|
619
|
-
var require_node = __commonJS({
|
|
620
|
-
"../../node_modules/list-it/node_modules/debug/src/node.js"(exports2, module2) {
|
|
621
|
-
"use strict";
|
|
622
|
-
var tty = require("tty");
|
|
623
|
-
var util = require("util");
|
|
624
|
-
exports2.init = init;
|
|
625
|
-
exports2.log = log;
|
|
626
|
-
exports2.formatArgs = formatArgs;
|
|
627
|
-
exports2.save = save;
|
|
628
|
-
exports2.load = load;
|
|
629
|
-
exports2.useColors = useColors;
|
|
630
|
-
exports2.destroy = util.deprecate(
|
|
631
|
-
() => {
|
|
632
|
-
},
|
|
633
|
-
"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."
|
|
634
|
-
);
|
|
635
|
-
exports2.colors = [6, 2, 3, 4, 5, 1];
|
|
636
|
-
try {
|
|
637
|
-
const supportsColor = require_supports_color();
|
|
638
|
-
if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
|
|
639
|
-
exports2.colors = [
|
|
640
|
-
20,
|
|
641
|
-
21,
|
|
642
|
-
26,
|
|
643
|
-
27,
|
|
644
|
-
32,
|
|
645
|
-
33,
|
|
646
|
-
38,
|
|
647
|
-
39,
|
|
648
|
-
40,
|
|
649
|
-
41,
|
|
650
|
-
42,
|
|
651
|
-
43,
|
|
652
|
-
44,
|
|
653
|
-
45,
|
|
654
|
-
56,
|
|
655
|
-
57,
|
|
656
|
-
62,
|
|
657
|
-
63,
|
|
658
|
-
68,
|
|
659
|
-
69,
|
|
660
|
-
74,
|
|
661
|
-
75,
|
|
662
|
-
76,
|
|
663
|
-
77,
|
|
664
|
-
78,
|
|
665
|
-
79,
|
|
666
|
-
80,
|
|
667
|
-
81,
|
|
668
|
-
92,
|
|
669
|
-
93,
|
|
670
|
-
98,
|
|
671
|
-
99,
|
|
672
|
-
112,
|
|
673
|
-
113,
|
|
674
|
-
128,
|
|
675
|
-
129,
|
|
676
|
-
134,
|
|
677
|
-
135,
|
|
678
|
-
148,
|
|
679
|
-
149,
|
|
680
|
-
160,
|
|
681
|
-
161,
|
|
682
|
-
162,
|
|
683
|
-
163,
|
|
684
|
-
164,
|
|
685
|
-
165,
|
|
686
|
-
166,
|
|
687
|
-
167,
|
|
688
|
-
168,
|
|
689
|
-
169,
|
|
690
|
-
170,
|
|
691
|
-
171,
|
|
692
|
-
172,
|
|
693
|
-
173,
|
|
694
|
-
178,
|
|
695
|
-
179,
|
|
696
|
-
184,
|
|
697
|
-
185,
|
|
698
|
-
196,
|
|
699
|
-
197,
|
|
700
|
-
198,
|
|
701
|
-
199,
|
|
702
|
-
200,
|
|
703
|
-
201,
|
|
704
|
-
202,
|
|
705
|
-
203,
|
|
706
|
-
204,
|
|
707
|
-
205,
|
|
708
|
-
206,
|
|
709
|
-
207,
|
|
710
|
-
208,
|
|
711
|
-
209,
|
|
712
|
-
214,
|
|
713
|
-
215,
|
|
714
|
-
220,
|
|
715
|
-
221
|
|
716
|
-
];
|
|
717
|
-
}
|
|
718
|
-
} catch (error) {
|
|
719
|
-
}
|
|
720
|
-
exports2.inspectOpts = Object.keys(process.env).filter((key) => {
|
|
721
|
-
return /^debug_/i.test(key);
|
|
722
|
-
}).reduce((obj, key) => {
|
|
723
|
-
const prop = key.substring(6).toLowerCase().replace(/_([a-z])/g, (_, k) => {
|
|
724
|
-
return k.toUpperCase();
|
|
725
|
-
});
|
|
726
|
-
let val = process.env[key];
|
|
727
|
-
if (/^(yes|on|true|enabled)$/i.test(val)) {
|
|
728
|
-
val = true;
|
|
729
|
-
} else if (/^(no|off|false|disabled)$/i.test(val)) {
|
|
730
|
-
val = false;
|
|
731
|
-
} else if (val === "null") {
|
|
732
|
-
val = null;
|
|
733
|
-
} else {
|
|
734
|
-
val = Number(val);
|
|
735
|
-
}
|
|
736
|
-
obj[prop] = val;
|
|
737
|
-
return obj;
|
|
738
|
-
}, {});
|
|
739
|
-
function useColors() {
|
|
740
|
-
return "colors" in exports2.inspectOpts ? Boolean(exports2.inspectOpts.colors) : tty.isatty(process.stderr.fd);
|
|
741
|
-
}
|
|
742
|
-
function formatArgs(args2) {
|
|
743
|
-
const { namespace: name, useColors: useColors2 } = this;
|
|
744
|
-
if (useColors2) {
|
|
745
|
-
const c = this.color;
|
|
746
|
-
const colorCode = "\x1B[3" + (c < 8 ? c : "8;5;" + c);
|
|
747
|
-
const prefix = ` ${colorCode};1m${name} \x1B[0m`;
|
|
748
|
-
args2[0] = prefix + args2[0].split("\n").join("\n" + prefix);
|
|
749
|
-
args2.push(colorCode + "m+" + module2.exports.humanize(this.diff) + "\x1B[0m");
|
|
750
|
-
} else {
|
|
751
|
-
args2[0] = getDate() + name + " " + args2[0];
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
function getDate() {
|
|
755
|
-
if (exports2.inspectOpts.hideDate) {
|
|
756
|
-
return "";
|
|
757
|
-
}
|
|
758
|
-
return (/* @__PURE__ */ new Date()).toISOString() + " ";
|
|
759
|
-
}
|
|
760
|
-
function log(...args2) {
|
|
761
|
-
return process.stderr.write(util.formatWithOptions(exports2.inspectOpts, ...args2) + "\n");
|
|
762
|
-
}
|
|
763
|
-
function save(namespaces) {
|
|
764
|
-
if (namespaces) {
|
|
765
|
-
process.env.DEBUG = namespaces;
|
|
766
|
-
} else {
|
|
767
|
-
delete process.env.DEBUG;
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
function load() {
|
|
771
|
-
return process.env.DEBUG;
|
|
772
|
-
}
|
|
773
|
-
function init(debug) {
|
|
774
|
-
debug.inspectOpts = {};
|
|
775
|
-
const keys = Object.keys(exports2.inspectOpts);
|
|
776
|
-
for (let i = 0; i < keys.length; i++) {
|
|
777
|
-
debug.inspectOpts[keys[i]] = exports2.inspectOpts[keys[i]];
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
module2.exports = require_common()(exports2);
|
|
781
|
-
var { formatters } = module2.exports;
|
|
782
|
-
formatters.o = function(v) {
|
|
783
|
-
this.inspectOpts.colors = this.useColors;
|
|
784
|
-
return util.inspect(v, this.inspectOpts).split("\n").map((str) => str.trim()).join(" ");
|
|
785
|
-
};
|
|
786
|
-
formatters.O = function(v) {
|
|
787
|
-
this.inspectOpts.colors = this.useColors;
|
|
788
|
-
return util.inspect(v, this.inspectOpts);
|
|
789
|
-
};
|
|
790
|
-
}
|
|
791
|
-
});
|
|
792
|
-
|
|
793
|
-
// ../../node_modules/list-it/node_modules/debug/src/index.js
|
|
794
|
-
var require_src = __commonJS({
|
|
795
|
-
"../../node_modules/list-it/node_modules/debug/src/index.js"(exports2, module2) {
|
|
796
|
-
"use strict";
|
|
797
|
-
if (typeof process === "undefined" || process.type === "renderer" || process.browser === true || process.__nwjs) {
|
|
798
|
-
module2.exports = require_browser();
|
|
799
|
-
} else {
|
|
800
|
-
module2.exports = require_node();
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
});
|
|
804
|
-
|
|
805
|
-
// ../../node_modules/eastasianwidth/eastasianwidth.js
|
|
806
|
-
var require_eastasianwidth = __commonJS({
|
|
807
|
-
"../../node_modules/eastasianwidth/eastasianwidth.js"(exports2, module2) {
|
|
808
|
-
"use strict";
|
|
809
|
-
var eaw = {};
|
|
810
|
-
if ("undefined" == typeof module2) {
|
|
811
|
-
window.eastasianwidth = eaw;
|
|
812
|
-
} else {
|
|
813
|
-
module2.exports = eaw;
|
|
814
|
-
}
|
|
815
|
-
eaw.eastAsianWidth = function(character) {
|
|
816
|
-
var x = character.charCodeAt(0);
|
|
817
|
-
var y = character.length == 2 ? character.charCodeAt(1) : 0;
|
|
818
|
-
var codePoint = x;
|
|
819
|
-
if (55296 <= x && x <= 56319 && (56320 <= y && y <= 57343)) {
|
|
820
|
-
x &= 1023;
|
|
821
|
-
y &= 1023;
|
|
822
|
-
codePoint = x << 10 | y;
|
|
823
|
-
codePoint += 65536;
|
|
824
|
-
}
|
|
825
|
-
if (12288 == codePoint || 65281 <= codePoint && codePoint <= 65376 || 65504 <= codePoint && codePoint <= 65510) {
|
|
826
|
-
return "F";
|
|
827
|
-
}
|
|
828
|
-
if (8361 == codePoint || 65377 <= codePoint && codePoint <= 65470 || 65474 <= codePoint && codePoint <= 65479 || 65482 <= codePoint && codePoint <= 65487 || 65490 <= codePoint && codePoint <= 65495 || 65498 <= codePoint && codePoint <= 65500 || 65512 <= codePoint && codePoint <= 65518) {
|
|
829
|
-
return "H";
|
|
830
|
-
}
|
|
831
|
-
if (4352 <= codePoint && codePoint <= 4447 || 4515 <= codePoint && codePoint <= 4519 || 4602 <= codePoint && codePoint <= 4607 || 9001 <= codePoint && codePoint <= 9002 || 11904 <= codePoint && codePoint <= 11929 || 11931 <= codePoint && codePoint <= 12019 || 12032 <= codePoint && codePoint <= 12245 || 12272 <= codePoint && codePoint <= 12283 || 12289 <= codePoint && codePoint <= 12350 || 12353 <= codePoint && codePoint <= 12438 || 12441 <= codePoint && codePoint <= 12543 || 12549 <= codePoint && codePoint <= 12589 || 12593 <= codePoint && codePoint <= 12686 || 12688 <= codePoint && codePoint <= 12730 || 12736 <= codePoint && codePoint <= 12771 || 12784 <= codePoint && codePoint <= 12830 || 12832 <= codePoint && codePoint <= 12871 || 12880 <= codePoint && codePoint <= 13054 || 13056 <= codePoint && codePoint <= 19903 || 19968 <= codePoint && codePoint <= 42124 || 42128 <= codePoint && codePoint <= 42182 || 43360 <= codePoint && codePoint <= 43388 || 44032 <= codePoint && codePoint <= 55203 || 55216 <= codePoint && codePoint <= 55238 || 55243 <= codePoint && codePoint <= 55291 || 63744 <= codePoint && codePoint <= 64255 || 65040 <= codePoint && codePoint <= 65049 || 65072 <= codePoint && codePoint <= 65106 || 65108 <= codePoint && codePoint <= 65126 || 65128 <= codePoint && codePoint <= 65131 || 110592 <= codePoint && codePoint <= 110593 || 127488 <= codePoint && codePoint <= 127490 || 127504 <= codePoint && codePoint <= 127546 || 127552 <= codePoint && codePoint <= 127560 || 127568 <= codePoint && codePoint <= 127569 || 131072 <= codePoint && codePoint <= 194367 || 177984 <= codePoint && codePoint <= 196605 || 196608 <= codePoint && codePoint <= 262141) {
|
|
832
|
-
return "W";
|
|
833
|
-
}
|
|
834
|
-
if (32 <= codePoint && codePoint <= 126 || 162 <= codePoint && codePoint <= 163 || 165 <= codePoint && codePoint <= 166 || 172 == codePoint || 175 == codePoint || 10214 <= codePoint && codePoint <= 10221 || 10629 <= codePoint && codePoint <= 10630) {
|
|
835
|
-
return "Na";
|
|
836
|
-
}
|
|
837
|
-
if (161 == codePoint || 164 == codePoint || 167 <= codePoint && codePoint <= 168 || 170 == codePoint || 173 <= codePoint && codePoint <= 174 || 176 <= codePoint && codePoint <= 180 || 182 <= codePoint && codePoint <= 186 || 188 <= codePoint && codePoint <= 191 || 198 == codePoint || 208 == codePoint || 215 <= codePoint && codePoint <= 216 || 222 <= codePoint && codePoint <= 225 || 230 == codePoint || 232 <= codePoint && codePoint <= 234 || 236 <= codePoint && codePoint <= 237 || 240 == codePoint || 242 <= codePoint && codePoint <= 243 || 247 <= codePoint && codePoint <= 250 || 252 == codePoint || 254 == codePoint || 257 == codePoint || 273 == codePoint || 275 == codePoint || 283 == codePoint || 294 <= codePoint && codePoint <= 295 || 299 == codePoint || 305 <= codePoint && codePoint <= 307 || 312 == codePoint || 319 <= codePoint && codePoint <= 322 || 324 == codePoint || 328 <= codePoint && codePoint <= 331 || 333 == codePoint || 338 <= codePoint && codePoint <= 339 || 358 <= codePoint && codePoint <= 359 || 363 == codePoint || 462 == codePoint || 464 == codePoint || 466 == codePoint || 468 == codePoint || 470 == codePoint || 472 == codePoint || 474 == codePoint || 476 == codePoint || 593 == codePoint || 609 == codePoint || 708 == codePoint || 711 == codePoint || 713 <= codePoint && codePoint <= 715 || 717 == codePoint || 720 == codePoint || 728 <= codePoint && codePoint <= 731 || 733 == codePoint || 735 == codePoint || 768 <= codePoint && codePoint <= 879 || 913 <= codePoint && codePoint <= 929 || 931 <= codePoint && codePoint <= 937 || 945 <= codePoint && codePoint <= 961 || 963 <= codePoint && codePoint <= 969 || 1025 == codePoint || 1040 <= codePoint && codePoint <= 1103 || 1105 == codePoint || 8208 == codePoint || 8211 <= codePoint && codePoint <= 8214 || 8216 <= codePoint && codePoint <= 8217 || 8220 <= codePoint && codePoint <= 8221 || 8224 <= codePoint && codePoint <= 8226 || 8228 <= codePoint && codePoint <= 8231 || 8240 == codePoint || 8242 <= codePoint && codePoint <= 8243 || 8245 == codePoint || 8251 == codePoint || 8254 == codePoint || 8308 == codePoint || 8319 == codePoint || 8321 <= codePoint && codePoint <= 8324 || 8364 == codePoint || 8451 == codePoint || 8453 == codePoint || 8457 == codePoint || 8467 == codePoint || 8470 == codePoint || 8481 <= codePoint && codePoint <= 8482 || 8486 == codePoint || 8491 == codePoint || 8531 <= codePoint && codePoint <= 8532 || 8539 <= codePoint && codePoint <= 8542 || 8544 <= codePoint && codePoint <= 8555 || 8560 <= codePoint && codePoint <= 8569 || 8585 == codePoint || 8592 <= codePoint && codePoint <= 8601 || 8632 <= codePoint && codePoint <= 8633 || 8658 == codePoint || 8660 == codePoint || 8679 == codePoint || 8704 == codePoint || 8706 <= codePoint && codePoint <= 8707 || 8711 <= codePoint && codePoint <= 8712 || 8715 == codePoint || 8719 == codePoint || 8721 == codePoint || 8725 == codePoint || 8730 == codePoint || 8733 <= codePoint && codePoint <= 8736 || 8739 == codePoint || 8741 == codePoint || 8743 <= codePoint && codePoint <= 8748 || 8750 == codePoint || 8756 <= codePoint && codePoint <= 8759 || 8764 <= codePoint && codePoint <= 8765 || 8776 == codePoint || 8780 == codePoint || 8786 == codePoint || 8800 <= codePoint && codePoint <= 8801 || 8804 <= codePoint && codePoint <= 8807 || 8810 <= codePoint && codePoint <= 8811 || 8814 <= codePoint && codePoint <= 8815 || 8834 <= codePoint && codePoint <= 8835 || 8838 <= codePoint && codePoint <= 8839 || 8853 == codePoint || 8857 == codePoint || 8869 == codePoint || 8895 == codePoint || 8978 == codePoint || 9312 <= codePoint && codePoint <= 9449 || 9451 <= codePoint && codePoint <= 9547 || 9552 <= codePoint && codePoint <= 9587 || 9600 <= codePoint && codePoint <= 9615 || 9618 <= codePoint && codePoint <= 9621 || 9632 <= codePoint && codePoint <= 9633 || 9635 <= codePoint && codePoint <= 9641 || 9650 <= codePoint && codePoint <= 9651 || 9654 <= codePoint && codePoint <= 9655 || 9660 <= codePoint && codePoint <= 9661 || 9664 <= codePoint && codePoint <= 9665 || 9670 <= codePoint && codePoint <= 9672 || 9675 == codePoint || 9678 <= codePoint && codePoint <= 9681 || 9698 <= codePoint && codePoint <= 9701 || 9711 == codePoint || 9733 <= codePoint && codePoint <= 9734 || 9737 == codePoint || 9742 <= codePoint && codePoint <= 9743 || 9748 <= codePoint && codePoint <= 9749 || 9756 == codePoint || 9758 == codePoint || 9792 == codePoint || 9794 == codePoint || 9824 <= codePoint && codePoint <= 9825 || 9827 <= codePoint && codePoint <= 9829 || 9831 <= codePoint && codePoint <= 9834 || 9836 <= codePoint && codePoint <= 9837 || 9839 == codePoint || 9886 <= codePoint && codePoint <= 9887 || 9918 <= codePoint && codePoint <= 9919 || 9924 <= codePoint && codePoint <= 9933 || 9935 <= codePoint && codePoint <= 9953 || 9955 == codePoint || 9960 <= codePoint && codePoint <= 9983 || 10045 == codePoint || 10071 == codePoint || 10102 <= codePoint && codePoint <= 10111 || 11093 <= codePoint && codePoint <= 11097 || 12872 <= codePoint && codePoint <= 12879 || 57344 <= codePoint && codePoint <= 63743 || 65024 <= codePoint && codePoint <= 65039 || 65533 == codePoint || 127232 <= codePoint && codePoint <= 127242 || 127248 <= codePoint && codePoint <= 127277 || 127280 <= codePoint && codePoint <= 127337 || 127344 <= codePoint && codePoint <= 127386 || 917760 <= codePoint && codePoint <= 917999 || 983040 <= codePoint && codePoint <= 1048573 || 1048576 <= codePoint && codePoint <= 1114109) {
|
|
838
|
-
return "A";
|
|
839
|
-
}
|
|
840
|
-
return "N";
|
|
841
|
-
};
|
|
842
|
-
eaw.characterLength = function(character) {
|
|
843
|
-
var code = this.eastAsianWidth(character);
|
|
844
|
-
if (code == "F" || code == "W" || code == "A") {
|
|
845
|
-
return 2;
|
|
846
|
-
} else {
|
|
847
|
-
return 1;
|
|
848
|
-
}
|
|
849
|
-
};
|
|
850
|
-
function stringToArray(string) {
|
|
851
|
-
return string.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
|
|
852
|
-
}
|
|
853
|
-
eaw.length = function(string) {
|
|
854
|
-
var characters = stringToArray(string);
|
|
855
|
-
var len = 0;
|
|
856
|
-
for (var i = 0; i < characters.length; i++) {
|
|
857
|
-
len = len + this.characterLength(characters[i]);
|
|
858
|
-
}
|
|
859
|
-
return len;
|
|
860
|
-
};
|
|
861
|
-
eaw.slice = function(text, start, end) {
|
|
862
|
-
textLen = eaw.length(text);
|
|
863
|
-
start = start ? start : 0;
|
|
864
|
-
end = end ? end : 1;
|
|
865
|
-
if (start < 0) {
|
|
866
|
-
start = textLen + start;
|
|
867
|
-
}
|
|
868
|
-
if (end < 0) {
|
|
869
|
-
end = textLen + end;
|
|
870
|
-
}
|
|
871
|
-
var result = "";
|
|
872
|
-
var eawLen = 0;
|
|
873
|
-
var chars = stringToArray(text);
|
|
874
|
-
for (var i = 0; i < chars.length; i++) {
|
|
875
|
-
var char = chars[i];
|
|
876
|
-
var charLen = eaw.length(char);
|
|
877
|
-
if (eawLen >= start - (charLen == 2 ? 1 : 0)) {
|
|
878
|
-
if (eawLen + charLen <= end) {
|
|
879
|
-
result += char;
|
|
880
|
-
} else {
|
|
881
|
-
break;
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
eawLen += charLen;
|
|
885
|
-
}
|
|
886
|
-
return result;
|
|
887
|
-
};
|
|
888
|
-
}
|
|
889
|
-
});
|
|
890
|
-
|
|
891
|
-
// ../../node_modules/list-it/lib/data-cell.js
|
|
892
|
-
var require_data_cell = __commonJS({
|
|
893
|
-
"../../node_modules/list-it/lib/data-cell.js"(exports2, module2) {
|
|
894
|
-
"use strict";
|
|
895
|
-
var eaw = require_eastasianwidth();
|
|
896
|
-
function DataCell() {
|
|
897
|
-
this.data = "";
|
|
898
|
-
}
|
|
899
|
-
module2.exports = DataCell;
|
|
900
|
-
DataCell.prototype.getData = function() {
|
|
901
|
-
return this.data;
|
|
902
|
-
};
|
|
903
|
-
DataCell.prototype.setData = function(data) {
|
|
904
|
-
this.data = data;
|
|
905
|
-
};
|
|
906
|
-
DataCell.prototype.visibleLength = function() {
|
|
907
|
-
if (typeof this.data != "string") {
|
|
908
|
-
return ("" + this.data).length;
|
|
909
|
-
}
|
|
910
|
-
return DataCell.visibleLength(this.data);
|
|
911
|
-
};
|
|
912
|
-
DataCell.visibleLength = function(data) {
|
|
913
|
-
const s = data.replace(/\x1b[^m]*m/g, "");
|
|
914
|
-
return eaw.length(s);
|
|
915
|
-
};
|
|
916
|
-
}
|
|
917
|
-
});
|
|
918
|
-
|
|
919
|
-
// ../../node_modules/list-it/lib/row.js
|
|
920
|
-
var require_row = __commonJS({
|
|
921
|
-
"../../node_modules/list-it/lib/row.js"(exports2, module2) {
|
|
922
|
-
"use strict";
|
|
923
|
-
function Row() {
|
|
924
|
-
this.cells = [];
|
|
925
|
-
this.empty = true;
|
|
926
|
-
this.fixed = false;
|
|
927
|
-
}
|
|
928
|
-
module2.exports = Row;
|
|
929
|
-
Row.prototype.getCellLength = function() {
|
|
930
|
-
return this.cells.length;
|
|
931
|
-
};
|
|
932
|
-
Row.prototype.getCell = function(idx) {
|
|
933
|
-
return this.cells[idx];
|
|
934
|
-
};
|
|
935
|
-
Row.prototype.pushCell = function(cell) {
|
|
936
|
-
if (this.isFixed()) {
|
|
937
|
-
throw "pushCell Fail, The row was already fixed.";
|
|
938
|
-
}
|
|
939
|
-
this.empty = false;
|
|
940
|
-
return this.cells.push(cell);
|
|
941
|
-
};
|
|
942
|
-
Row.prototype.fix = function() {
|
|
943
|
-
this.fixed = true;
|
|
944
|
-
};
|
|
945
|
-
Row.prototype.isEmpty = function() {
|
|
946
|
-
return this.empty;
|
|
947
|
-
};
|
|
948
|
-
Row.prototype.isFixed = function() {
|
|
949
|
-
return this.fixed;
|
|
950
|
-
};
|
|
951
|
-
}
|
|
952
|
-
});
|
|
953
|
-
|
|
954
|
-
// ../../node_modules/list-it/lib/column.js
|
|
955
|
-
var require_column = __commonJS({
|
|
956
|
-
"../../node_modules/list-it/lib/column.js"(exports2, module2) {
|
|
957
|
-
"use strict";
|
|
958
|
-
var DataCell = require_data_cell();
|
|
959
|
-
function Column() {
|
|
960
|
-
this.opt = {
|
|
961
|
-
"autoAlign": false
|
|
962
|
-
};
|
|
963
|
-
this.width = 0;
|
|
964
|
-
this.textWidth = null;
|
|
965
|
-
this.intLen = 0;
|
|
966
|
-
this.fracLen = 0;
|
|
967
|
-
this.expLen = 0;
|
|
968
|
-
this.cellAtRow = {};
|
|
969
|
-
this.header = null;
|
|
970
|
-
}
|
|
971
|
-
module2.exports = Column;
|
|
972
|
-
Column.prototype.getWidth = function() {
|
|
973
|
-
return this.width;
|
|
974
|
-
};
|
|
975
|
-
Column.prototype.setTextWidth = function(textWidth) {
|
|
976
|
-
this.textWidth = textWidth;
|
|
977
|
-
};
|
|
978
|
-
Column.prototype.setCellAt = function(row, cell) {
|
|
979
|
-
this.cellAtRow[row] = cell;
|
|
980
|
-
};
|
|
981
|
-
Column.prototype.setHeader = function(header) {
|
|
982
|
-
this.header = header;
|
|
983
|
-
};
|
|
984
|
-
Column.prototype.hasHeader = function() {
|
|
985
|
-
return this.header != null;
|
|
986
|
-
};
|
|
987
|
-
Column.prototype.updateWidth = function() {
|
|
988
|
-
const headerWidth = !this.hasHeader() ? 0 : DataCell.visibleLength("" + this.header);
|
|
989
|
-
this.width = headerWidth;
|
|
990
|
-
Object.keys(this.cellAtRow).forEach((key) => {
|
|
991
|
-
const cell = this.cellAtRow[key];
|
|
992
|
-
const data = cell.getData();
|
|
993
|
-
let width = cell.visibleLength();
|
|
994
|
-
if (typeof data == "number") {
|
|
995
|
-
if (this.opt.autoAlign) {
|
|
996
|
-
this.updateNumWidth(data);
|
|
997
|
-
width = this.getNumMaxWidth();
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
if (width > this.width) {
|
|
1001
|
-
this.width = width;
|
|
1002
|
-
}
|
|
1003
|
-
if (typeof data == "string") {
|
|
1004
|
-
if (this.textWidth && this.textWidth > headerWidth) {
|
|
1005
|
-
if (this.width > this.textWidth) {
|
|
1006
|
-
this.width = this.textWidth;
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
});
|
|
1011
|
-
};
|
|
1012
|
-
Column.prototype.formatColumnHeader = function() {
|
|
1013
|
-
if (!this.hasHeader()) {
|
|
1014
|
-
return null;
|
|
1015
|
-
}
|
|
1016
|
-
const width = this.getWidth();
|
|
1017
|
-
const header = this.header;
|
|
1018
|
-
const headerWidth = DataCell.visibleLength("" + header);
|
|
1019
|
-
if (header.length == headerWidth && width - headerWidth <= 0) {
|
|
1020
|
-
return ("" + header).substring(0, width);
|
|
1021
|
-
}
|
|
1022
|
-
return "" + header + " ".repeat(width - headerWidth);
|
|
1023
|
-
};
|
|
1024
|
-
Column.prototype.formatCell = function(data) {
|
|
1025
|
-
const width = this.getWidth();
|
|
1026
|
-
if (this.opt.autoAlign) {
|
|
1027
|
-
if (typeof data == "number") {
|
|
1028
|
-
return this.makeAutoAlignNum(data).padStart(width, " ");
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
const dataWidth = DataCell.visibleLength("" + data);
|
|
1032
|
-
if (data.length == dataWidth && width - dataWidth <= 0) {
|
|
1033
|
-
return ("" + data).substring(0, width);
|
|
1034
|
-
}
|
|
1035
|
-
return "" + data + " ".repeat(width - dataWidth);
|
|
1036
|
-
};
|
|
1037
|
-
Column.prototype.setAutoAlign = function(autoAlign) {
|
|
1038
|
-
this.opt.autoAlign = autoAlign;
|
|
1039
|
-
};
|
|
1040
|
-
Column.prototype.updateNumWidth = function(num) {
|
|
1041
|
-
const numInfo = this.analyzeNumber(num);
|
|
1042
|
-
const intLen = numInfo.intStr.length;
|
|
1043
|
-
const fracLen = numInfo.fracStr.length;
|
|
1044
|
-
const expLen = numInfo.expStr.length;
|
|
1045
|
-
if (intLen > this.intLen) {
|
|
1046
|
-
this.intLen = intLen;
|
|
1047
|
-
}
|
|
1048
|
-
if (fracLen > this.fracLen) {
|
|
1049
|
-
this.fracLen = fracLen;
|
|
1050
|
-
}
|
|
1051
|
-
if (expLen > this.expLen) {
|
|
1052
|
-
this.expLen = expLen;
|
|
1053
|
-
}
|
|
1054
|
-
};
|
|
1055
|
-
Column.prototype.getNumMaxWidth = function() {
|
|
1056
|
-
return this.intLen + this.fracLen + (this.fracLen > 0 ? 1 : 0) + this.expLen + (this.expLen > 0 ? 1 : 0);
|
|
1057
|
-
};
|
|
1058
|
-
Column.prototype.makeAutoAlignNum = function(num) {
|
|
1059
|
-
const numInfo = this.analyzeNumber(num);
|
|
1060
|
-
const intStr = numInfo.intStr.padStart(this.intLen, " ");
|
|
1061
|
-
const fracStr = numInfo.expStr != "" ? numInfo.fracStr.padEnd(this.fracLen, "0") : numInfo.fracStr.padEnd(this.fracLen, " ");
|
|
1062
|
-
const expStr = numInfo.expStr.padEnd(this.expLen, " ");
|
|
1063
|
-
if (numInfo.expStr != "") {
|
|
1064
|
-
return [intStr, ".", fracStr, "e", expStr].join("");
|
|
1065
|
-
}
|
|
1066
|
-
if (numInfo.pointPos >= 0) {
|
|
1067
|
-
if (this.expLen > 0) {
|
|
1068
|
-
return [intStr, ".", fracStr, " ", expStr].join("");
|
|
1069
|
-
}
|
|
1070
|
-
return [intStr, ".", fracStr].join("");
|
|
1071
|
-
} else if (this.fracLen == 0) {
|
|
1072
|
-
return intStr;
|
|
1073
|
-
}
|
|
1074
|
-
if (this.expLen > 0) {
|
|
1075
|
-
return [intStr, ".0", fracStr.substr(1), " ", expStr].join("");
|
|
1076
|
-
}
|
|
1077
|
-
return [intStr, ".0", fracStr.substr(1)].join("");
|
|
1078
|
-
};
|
|
1079
|
-
Column.prototype.analyzeNumber = function(num) {
|
|
1080
|
-
const s = "" + num;
|
|
1081
|
-
let intStr = "";
|
|
1082
|
-
let fracStr = "";
|
|
1083
|
-
const pointPos = s.indexOf(".");
|
|
1084
|
-
const expIndex = s.indexOf("e");
|
|
1085
|
-
if (expIndex >= 0) {
|
|
1086
|
-
if (pointPos < 0) {
|
|
1087
|
-
return {
|
|
1088
|
-
pointPos: expIndex,
|
|
1089
|
-
intStr: s.substr(0, expIndex),
|
|
1090
|
-
fracStr: "0",
|
|
1091
|
-
expStr: s.substr(expIndex + 1)
|
|
1092
|
-
};
|
|
1093
|
-
}
|
|
1094
|
-
return {
|
|
1095
|
-
pointPos,
|
|
1096
|
-
intStr: s.substr(0, pointPos),
|
|
1097
|
-
fracStr: s.substring(pointPos + 1, expIndex),
|
|
1098
|
-
expStr: s.substr(expIndex + 1)
|
|
1099
|
-
};
|
|
1100
|
-
}
|
|
1101
|
-
if (pointPos < 0) {
|
|
1102
|
-
intStr = s;
|
|
1103
|
-
} else {
|
|
1104
|
-
intStr = s.substr(0, pointPos);
|
|
1105
|
-
fracStr = s.substr(pointPos + 1);
|
|
1106
|
-
}
|
|
1107
|
-
return {
|
|
1108
|
-
"pointPos": pointPos,
|
|
1109
|
-
"intStr": intStr,
|
|
1110
|
-
"fracStr": fracStr,
|
|
1111
|
-
"expStr": ""
|
|
1112
|
-
};
|
|
1113
|
-
};
|
|
1114
|
-
}
|
|
1115
|
-
});
|
|
1116
|
-
|
|
1117
|
-
// ../../node_modules/ansi-escape-sequences/dist/index.cjs
|
|
1118
|
-
var require_dist = __commonJS({
|
|
1119
|
-
"../../node_modules/ansi-escape-sequences/dist/index.cjs"(exports2, module2) {
|
|
1120
|
-
"use strict";
|
|
1121
|
-
function isObject(input) {
|
|
1122
|
-
return typeof input === "object" && input !== null;
|
|
1123
|
-
}
|
|
1124
|
-
function isArrayLike(input) {
|
|
1125
|
-
return isObject(input) && typeof input.length === "number";
|
|
1126
|
-
}
|
|
1127
|
-
function arrayify(input) {
|
|
1128
|
-
if (Array.isArray(input)) {
|
|
1129
|
-
return input;
|
|
1130
|
-
} else if (input === void 0) {
|
|
1131
|
-
return [];
|
|
1132
|
-
} else if (isArrayLike(input) || input instanceof Set) {
|
|
1133
|
-
return Array.from(input);
|
|
1134
|
-
} else {
|
|
1135
|
-
return [input];
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
var csi = "\x1B[";
|
|
1139
|
-
var ansi = {};
|
|
1140
|
-
ansi.style = {
|
|
1141
|
-
reset: "\x1B[0m",
|
|
1142
|
-
bold: "\x1B[1m",
|
|
1143
|
-
italic: "\x1B[3m",
|
|
1144
|
-
underline: "\x1B[4m",
|
|
1145
|
-
fontDefault: "\x1B[10m",
|
|
1146
|
-
font2: "\x1B[11m",
|
|
1147
|
-
font3: "\x1B[12m",
|
|
1148
|
-
font4: "\x1B[13m",
|
|
1149
|
-
font5: "\x1B[14m",
|
|
1150
|
-
font6: "\x1B[15m",
|
|
1151
|
-
imageNegative: "\x1B[7m",
|
|
1152
|
-
imagePositive: "\x1B[27m",
|
|
1153
|
-
black: "\x1B[30m",
|
|
1154
|
-
red: "\x1B[31m",
|
|
1155
|
-
green: "\x1B[32m",
|
|
1156
|
-
yellow: "\x1B[33m",
|
|
1157
|
-
blue: "\x1B[34m",
|
|
1158
|
-
magenta: "\x1B[35m",
|
|
1159
|
-
cyan: "\x1B[36m",
|
|
1160
|
-
white: "\x1B[37m",
|
|
1161
|
-
grey: "\x1B[90m",
|
|
1162
|
-
gray: "\x1B[90m",
|
|
1163
|
-
brightRed: "\x1B[91m",
|
|
1164
|
-
brightGreen: "\x1B[92m",
|
|
1165
|
-
brightYellow: "\x1B[93m",
|
|
1166
|
-
brightBlue: "\x1B[94m",
|
|
1167
|
-
brightMagenta: "\x1B[95m",
|
|
1168
|
-
brightCyan: "\x1B[96m",
|
|
1169
|
-
brightWhite: "\x1B[97m",
|
|
1170
|
-
"bg-black": "\x1B[40m",
|
|
1171
|
-
"bg-red": "\x1B[41m",
|
|
1172
|
-
"bg-green": "\x1B[42m",
|
|
1173
|
-
"bg-yellow": "\x1B[43m",
|
|
1174
|
-
"bg-blue": "\x1B[44m",
|
|
1175
|
-
"bg-magenta": "\x1B[45m",
|
|
1176
|
-
"bg-cyan": "\x1B[46m",
|
|
1177
|
-
"bg-white": "\x1B[47m",
|
|
1178
|
-
"bg-grey": "\x1B[100m",
|
|
1179
|
-
"bg-gray": "\x1B[100m",
|
|
1180
|
-
"bg-brightRed": "\x1B[101m",
|
|
1181
|
-
"bg-brightGreen": "\x1B[102m",
|
|
1182
|
-
"bg-brightYellow": "\x1B[103m",
|
|
1183
|
-
"bg-brightBlue": "\x1B[104m",
|
|
1184
|
-
"bg-brightMagenta": "\x1B[105m",
|
|
1185
|
-
"bg-brightCyan": "\x1B[106m",
|
|
1186
|
-
"bg-brightWhite": "\x1B[107m"
|
|
1187
|
-
};
|
|
1188
|
-
ansi.rgb = function(r, g, b) {
|
|
1189
|
-
return `\x1B[38;2;${r};${g};${b}m`;
|
|
1190
|
-
};
|
|
1191
|
-
ansi.bgRgb = function(r, g, b) {
|
|
1192
|
-
return `\x1B[48;2;${r};${g};${b}m`;
|
|
1193
|
-
};
|
|
1194
|
-
ansi.styles = function(styles) {
|
|
1195
|
-
styles = arrayify(styles);
|
|
1196
|
-
return styles.map(function(effect) {
|
|
1197
|
-
const rgbMatches = effect.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
|
|
1198
|
-
const bgRgbMatches = effect.match(/bg-rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
|
|
1199
|
-
if (bgRgbMatches) {
|
|
1200
|
-
const [full, r, g, b] = bgRgbMatches;
|
|
1201
|
-
return ansi.bgRgb(r, g, b);
|
|
1202
|
-
} else if (rgbMatches) {
|
|
1203
|
-
const [full, r, g, b] = rgbMatches;
|
|
1204
|
-
return ansi.rgb(r, g, b);
|
|
1205
|
-
} else {
|
|
1206
|
-
return ansi.style[effect];
|
|
1207
|
-
}
|
|
1208
|
-
}).join("");
|
|
1209
|
-
};
|
|
1210
|
-
ansi.format = function(str, styleArray) {
|
|
1211
|
-
const re = /\[([\w\s-\(\),]+)\]{([^]*?)}/;
|
|
1212
|
-
let matches;
|
|
1213
|
-
str = String(str);
|
|
1214
|
-
if (!str) return "";
|
|
1215
|
-
while (matches = str.match(re)) {
|
|
1216
|
-
const inlineStyles = matches[1].split(/\s+/);
|
|
1217
|
-
const inlineString = matches[2];
|
|
1218
|
-
str = str.replace(matches[0], ansi.format(inlineString, inlineStyles));
|
|
1219
|
-
}
|
|
1220
|
-
return styleArray && styleArray.length ? ansi.styles(styleArray) + str + ansi.style.reset : str;
|
|
1221
|
-
};
|
|
1222
|
-
ansi.cursor = {
|
|
1223
|
-
/**
|
|
1224
|
-
* Moves the cursor `lines` cells up. If the cursor is already at the edge of the screen, this has no effect
|
|
1225
|
-
* @param [lines=1] {number}
|
|
1226
|
-
* @return {string}
|
|
1227
|
-
*/
|
|
1228
|
-
up: function(lines) {
|
|
1229
|
-
return csi + (lines || 1) + "A";
|
|
1230
|
-
},
|
|
1231
|
-
/**
|
|
1232
|
-
* Moves the cursor `lines` cells down. If the cursor is already at the edge of the screen, this has no effect
|
|
1233
|
-
* @param [lines=1] {number}
|
|
1234
|
-
* @return {string}
|
|
1235
|
-
*/
|
|
1236
|
-
down: function(lines) {
|
|
1237
|
-
return csi + (lines || 1) + "B";
|
|
1238
|
-
},
|
|
1239
|
-
/**
|
|
1240
|
-
* Moves the cursor `lines` cells forward. If the cursor is already at the edge of the screen, this has no effect
|
|
1241
|
-
* @param [lines=1] {number}
|
|
1242
|
-
* @return {string}
|
|
1243
|
-
*/
|
|
1244
|
-
forward: function(lines) {
|
|
1245
|
-
return csi + (lines || 1) + "C";
|
|
1246
|
-
},
|
|
1247
|
-
/**
|
|
1248
|
-
* Moves the cursor `lines` cells back. If the cursor is already at the edge of the screen, this has no effect
|
|
1249
|
-
* @param [lines=1] {number}
|
|
1250
|
-
* @return {string}
|
|
1251
|
-
*/
|
|
1252
|
-
back: function(lines) {
|
|
1253
|
-
return csi + (lines || 1) + "D";
|
|
1254
|
-
},
|
|
1255
|
-
/**
|
|
1256
|
-
* Moves cursor to beginning of the line n lines down.
|
|
1257
|
-
* @param [lines=1] {number}
|
|
1258
|
-
* @return {string}
|
|
1259
|
-
*/
|
|
1260
|
-
nextLine: function(lines) {
|
|
1261
|
-
return csi + (lines || 1) + "E";
|
|
1262
|
-
},
|
|
1263
|
-
/**
|
|
1264
|
-
* Moves cursor to beginning of the line n lines up.
|
|
1265
|
-
* @param [lines=1] {number}
|
|
1266
|
-
* @return {string}
|
|
1267
|
-
*/
|
|
1268
|
-
previousLine: function(lines) {
|
|
1269
|
-
return csi + (lines || 1) + "F";
|
|
1270
|
-
},
|
|
1271
|
-
/**
|
|
1272
|
-
* Moves the cursor to column n.
|
|
1273
|
-
* @param n {number} - column number
|
|
1274
|
-
* @return {string}
|
|
1275
|
-
*/
|
|
1276
|
-
horizontalAbsolute: function(n) {
|
|
1277
|
-
return csi + n + "G";
|
|
1278
|
-
},
|
|
1279
|
-
/**
|
|
1280
|
-
* Moves the cursor to row n, column m. The values are 1-based, and default to 1 (top left corner) if omitted.
|
|
1281
|
-
* @param n {number} - row number
|
|
1282
|
-
* @param m {number} - column number
|
|
1283
|
-
* @return {string}
|
|
1284
|
-
*/
|
|
1285
|
-
position: function(n, m) {
|
|
1286
|
-
return csi + (n || 1) + ";" + (m || 1) + "H";
|
|
1287
|
-
},
|
|
1288
|
-
/**
|
|
1289
|
-
* Hides the cursor
|
|
1290
|
-
*/
|
|
1291
|
-
hide: csi + "?25l",
|
|
1292
|
-
/**
|
|
1293
|
-
* Shows the cursor
|
|
1294
|
-
*/
|
|
1295
|
-
show: csi + "?25h"
|
|
1296
|
-
};
|
|
1297
|
-
ansi.erase = {
|
|
1298
|
-
/**
|
|
1299
|
-
* Clears part of the screen. If n is 0 (or missing), clear from cursor to end of screen. If n is 1, clear from cursor to beginning of the screen. If n is 2, clear entire screen.
|
|
1300
|
-
* @param n {number}
|
|
1301
|
-
* @return {string}
|
|
1302
|
-
*/
|
|
1303
|
-
display: function(n) {
|
|
1304
|
-
return csi + (n || 0) + "J";
|
|
1305
|
-
},
|
|
1306
|
-
/**
|
|
1307
|
-
* Erases part of the line. If n is zero (or missing), clear from cursor to the end of the line. If n is one, clear from cursor to beginning of the line. If n is two, clear entire line. Cursor position does not change.
|
|
1308
|
-
* @param n {number}
|
|
1309
|
-
* @return {string}
|
|
1310
|
-
*/
|
|
1311
|
-
inLine: function(n) {
|
|
1312
|
-
return csi + (n || 0) + "K";
|
|
1313
|
-
}
|
|
1314
|
-
};
|
|
1315
|
-
module2.exports = ansi;
|
|
1316
|
-
}
|
|
1317
|
-
});
|
|
1318
|
-
|
|
1319
|
-
// ../../node_modules/list-it/lib/list-it-buffer.js
|
|
1320
|
-
var require_list_it_buffer = __commonJS({
|
|
1321
|
-
"../../node_modules/list-it/lib/list-it-buffer.js"(exports2, module2) {
|
|
1322
|
-
"use strict";
|
|
1323
|
-
var debug = require_src()("list-it-buffer");
|
|
1324
|
-
var DataCell = require_data_cell();
|
|
1325
|
-
var Row = require_row();
|
|
1326
|
-
var Column = require_column();
|
|
1327
|
-
var ansi = require_dist();
|
|
1328
|
-
function ListItBuffer(opt) {
|
|
1329
|
-
opt = opt || {};
|
|
1330
|
-
this.opt = {
|
|
1331
|
-
"autoAlign": true,
|
|
1332
|
-
"columnWidth": null,
|
|
1333
|
-
"header": null,
|
|
1334
|
-
"headerBold": false,
|
|
1335
|
-
"headerColor": "",
|
|
1336
|
-
"headerUnderline": false
|
|
1337
|
-
};
|
|
1338
|
-
if (opt.header != null && !Array.isArray(opt.header)) {
|
|
1339
|
-
throw new Error([
|
|
1340
|
-
`Invalid header was specified. It must be an array, but (${JSON.stringify(opt.header)}):${typeof opt.header} was specified.`
|
|
1341
|
-
].join(" "));
|
|
1342
|
-
}
|
|
1343
|
-
if (opt.headerColor && !(opt.headerColor in COLORS)) {
|
|
1344
|
-
throw new Error([
|
|
1345
|
-
`Invalid color ${JSON.stringify(opt.headerColor)} was specified.`,
|
|
1346
|
-
"Available color names:",
|
|
1347
|
-
...AVAILABLE_COLORS.map((color) => `* ${JSON.stringify(color)}`)
|
|
1348
|
-
].join("\n"));
|
|
1349
|
-
}
|
|
1350
|
-
Object.keys(this.opt).forEach((key) => {
|
|
1351
|
-
if (key in opt) {
|
|
1352
|
-
this.opt[key] = opt[key];
|
|
1353
|
-
}
|
|
1354
|
-
});
|
|
1355
|
-
this.lines = [];
|
|
1356
|
-
this.columns = [];
|
|
1357
|
-
this.columnWidth = this.opt.columnWidth;
|
|
1358
|
-
if (this.opt.header) {
|
|
1359
|
-
this.setHeaderRow(this.opt.header);
|
|
1360
|
-
}
|
|
1361
|
-
}
|
|
1362
|
-
module2.exports = ListItBuffer;
|
|
1363
|
-
ListItBuffer.prototype.nl = function() {
|
|
1364
|
-
const lastRowIndex = this.lines.length - 1;
|
|
1365
|
-
if (lastRowIndex >= 0 && !this.lines[lastRowIndex].isFixed()) {
|
|
1366
|
-
this.lines[lastRowIndex].fix();
|
|
1367
|
-
}
|
|
1368
|
-
this.pushNewRow();
|
|
1369
|
-
return this;
|
|
1370
|
-
};
|
|
1371
|
-
ListItBuffer.prototype.d = function(data) {
|
|
1372
|
-
if (arguments.length > 1) {
|
|
1373
|
-
const array = Array.apply(null, arguments);
|
|
1374
|
-
if (ListItBuffer.isMultiDimensionalArray(array)) {
|
|
1375
|
-
array.forEach((row) => this.addRow(row));
|
|
1376
|
-
} else {
|
|
1377
|
-
array.forEach((data2) => this.d(data2));
|
|
1378
|
-
}
|
|
1379
|
-
return this;
|
|
1380
|
-
}
|
|
1381
|
-
if (Array.isArray(data)) {
|
|
1382
|
-
if (ListItBuffer.isMultiDimensionalArray(data)) {
|
|
1383
|
-
data.forEach((row) => this.addRow(row));
|
|
1384
|
-
} else if (ListItBuffer.isObjectArray(data)) {
|
|
1385
|
-
data = objectArrayToTable(data);
|
|
1386
|
-
if (!this.header && (this.opt.headerBold || this.opt.headerColor || this.opt.headerUnderline)) {
|
|
1387
|
-
this.setHeaderRow(data.shift());
|
|
1388
|
-
}
|
|
1389
|
-
data.forEach((row) => this.addRow(row));
|
|
1390
|
-
} else {
|
|
1391
|
-
this.addRow(data);
|
|
1392
|
-
}
|
|
1393
|
-
return this;
|
|
1394
|
-
}
|
|
1395
|
-
const rowidx = this.lines.length - 1;
|
|
1396
|
-
if (rowidx < 0 || this.lines[rowidx].isFixed()) {
|
|
1397
|
-
this.pushNewRow();
|
|
1398
|
-
}
|
|
1399
|
-
const cell = new DataCell();
|
|
1400
|
-
cell.setData(data);
|
|
1401
|
-
const iRow = this.lines.length - 1;
|
|
1402
|
-
let iCol = this.lines[iRow].getCellLength();
|
|
1403
|
-
if (iCol >= this.columns.length) {
|
|
1404
|
-
this.addColumn();
|
|
1405
|
-
}
|
|
1406
|
-
this.columns[iCol].setCellAt(iRow, cell);
|
|
1407
|
-
this.lines[iRow].pushCell(cell);
|
|
1408
|
-
return this;
|
|
1409
|
-
};
|
|
1410
|
-
ListItBuffer.isMultiDimensionalArray = function(arr) {
|
|
1411
|
-
if (!Array.isArray(arr)) {
|
|
1412
|
-
throw Error("The parameter arr must be array");
|
|
1413
|
-
}
|
|
1414
|
-
for (let element of arr) {
|
|
1415
|
-
if (!Array.isArray(element)) {
|
|
1416
|
-
return false;
|
|
1417
|
-
}
|
|
1418
|
-
}
|
|
1419
|
-
return true;
|
|
1420
|
-
};
|
|
1421
|
-
ListItBuffer.isObjectArray = function(arr) {
|
|
1422
|
-
if (!Array.isArray(arr)) {
|
|
1423
|
-
throw Error("The parameter arr must be array");
|
|
1424
|
-
}
|
|
1425
|
-
const ctor = arr[0].constructor;
|
|
1426
|
-
for (let element of arr) {
|
|
1427
|
-
if (typeof element != "object") {
|
|
1428
|
-
return false;
|
|
1429
|
-
} else {
|
|
1430
|
-
if (element.constructor.name != ctor.name) {
|
|
1431
|
-
return false;
|
|
1432
|
-
}
|
|
1433
|
-
}
|
|
1434
|
-
}
|
|
1435
|
-
return true;
|
|
1436
|
-
};
|
|
1437
|
-
ListItBuffer.prototype.addRow = function(row) {
|
|
1438
|
-
row.forEach((col) => {
|
|
1439
|
-
switch (typeof col) {
|
|
1440
|
-
case "string":
|
|
1441
|
-
case "number":
|
|
1442
|
-
this.d(col);
|
|
1443
|
-
break;
|
|
1444
|
-
default:
|
|
1445
|
-
this.d(col != null ? col.toString() : "(null)");
|
|
1446
|
-
break;
|
|
1447
|
-
}
|
|
1448
|
-
});
|
|
1449
|
-
this.nl();
|
|
1450
|
-
};
|
|
1451
|
-
ListItBuffer.prototype.pushNewRow = function() {
|
|
1452
|
-
this.lines.push(new Row());
|
|
1453
|
-
};
|
|
1454
|
-
ListItBuffer.prototype.toString = function() {
|
|
1455
|
-
const rows = [];
|
|
1456
|
-
this.columns.forEach((column, iCol) => {
|
|
1457
|
-
if (this.header != null) {
|
|
1458
|
-
column.setHeader(this.header[iCol] || "");
|
|
1459
|
-
}
|
|
1460
|
-
column.setTextWidth(this.getColumnWidth(iCol));
|
|
1461
|
-
column.updateWidth();
|
|
1462
|
-
});
|
|
1463
|
-
if (this.header != null) {
|
|
1464
|
-
const headerLine = this.applyHeaderStyleOption(
|
|
1465
|
-
this.columns.map((column) => column.formatColumnHeader()).join(" ")
|
|
1466
|
-
);
|
|
1467
|
-
rows.push(headerLine);
|
|
1468
|
-
const headerUnderline = this.generateHeaderUnderline();
|
|
1469
|
-
if (headerUnderline) {
|
|
1470
|
-
rows.push(headerUnderline);
|
|
1471
|
-
}
|
|
1472
|
-
}
|
|
1473
|
-
this.lines.forEach((line) => {
|
|
1474
|
-
if (line.isFixed() || !line.isEmpty()) {
|
|
1475
|
-
if (line.isEmpty()) {
|
|
1476
|
-
rows.push("\n");
|
|
1477
|
-
} else {
|
|
1478
|
-
rows.push(this.columns.map((column, iCol) => {
|
|
1479
|
-
const cell = line.getCell(iCol);
|
|
1480
|
-
const data = cell.getData();
|
|
1481
|
-
return column.formatCell(data);
|
|
1482
|
-
}).join(" "));
|
|
1483
|
-
}
|
|
1484
|
-
}
|
|
1485
|
-
});
|
|
1486
|
-
return rows.join("\n");
|
|
1487
|
-
};
|
|
1488
|
-
var COLORS = {};
|
|
1489
|
-
var BGCOLORS = {};
|
|
1490
|
-
Object.keys(ansi.style).forEach((key) => {
|
|
1491
|
-
const value = ansi.style[key];
|
|
1492
|
-
if (/^bg-/.test(key)) {
|
|
1493
|
-
BGCOLORS[key.substr(3)] = value;
|
|
1494
|
-
} else {
|
|
1495
|
-
COLORS[key] = value;
|
|
1496
|
-
debug(`COLOR-KEY: ${key}`);
|
|
1497
|
-
}
|
|
1498
|
-
});
|
|
1499
|
-
Object.keys(COLORS).forEach((key) => {
|
|
1500
|
-
if (!(key in BGCOLORS)) {
|
|
1501
|
-
delete COLORS[key];
|
|
1502
|
-
debug(`remove COLOR-KEY: ${key}`);
|
|
1503
|
-
}
|
|
1504
|
-
});
|
|
1505
|
-
var AVAILABLE_COLORS = Object.keys(COLORS);
|
|
1506
|
-
debug(`AVAILABLE_COLORS:${JSON.stringify(AVAILABLE_COLORS)}`);
|
|
1507
|
-
ListItBuffer.prototype.applyHeaderStyleOption = function(line) {
|
|
1508
|
-
if (!this.opt.headerBold && !this.opt.headerColor) {
|
|
1509
|
-
return line;
|
|
1510
|
-
}
|
|
1511
|
-
const textBuffer = [];
|
|
1512
|
-
if (this.opt.headerBold) {
|
|
1513
|
-
textBuffer.push(ansi.style.bold);
|
|
1514
|
-
}
|
|
1515
|
-
if (this.opt.headerColor) {
|
|
1516
|
-
textBuffer.push(COLORS[this.opt.headerColor]);
|
|
1517
|
-
}
|
|
1518
|
-
textBuffer.push(line);
|
|
1519
|
-
textBuffer.push(ansi.style.reset);
|
|
1520
|
-
return textBuffer.join("");
|
|
1521
|
-
};
|
|
1522
|
-
ListItBuffer.prototype.generateHeaderUnderline = function() {
|
|
1523
|
-
if (!this.opt.headerUnderline) {
|
|
1524
|
-
return null;
|
|
1525
|
-
}
|
|
1526
|
-
if (this.header == null) {
|
|
1527
|
-
return null;
|
|
1528
|
-
}
|
|
1529
|
-
return this.columns.map(
|
|
1530
|
-
(column) => "-".repeat(column.getWidth())
|
|
1531
|
-
).join(" ");
|
|
1532
|
-
};
|
|
1533
|
-
function objectArrayToTable(objects) {
|
|
1534
|
-
const keys = Object.keys(objects[0]);
|
|
1535
|
-
const body = objects.map((item) => keys.map((key) => {
|
|
1536
|
-
if (item[key] != null && typeof item[key] == "object" && item[key].constructor.name == "Date") {
|
|
1537
|
-
return item[key].toISOString();
|
|
1538
|
-
}
|
|
1539
|
-
return item[key];
|
|
1540
|
-
}));
|
|
1541
|
-
return [keys, ...body];
|
|
1542
|
-
}
|
|
1543
|
-
ListItBuffer.prototype.setColumnWidth = function(indexOfColumns, width) {
|
|
1544
|
-
this.columnWidth = this.columnWidth || [];
|
|
1545
|
-
if (typeof indexOfColumns !== "number") {
|
|
1546
|
-
throw new Error("indexOfColumns must be a number");
|
|
1547
|
-
}
|
|
1548
|
-
if (!width) {
|
|
1549
|
-
delete this.columnWidth[indexOfColumns];
|
|
1550
|
-
} else {
|
|
1551
|
-
if (typeof width !== "number") {
|
|
1552
|
-
throw new Error("width must be a number");
|
|
1553
|
-
}
|
|
1554
|
-
this.columnWidth[indexOfColumns] = width;
|
|
1555
|
-
}
|
|
1556
|
-
return this;
|
|
1557
|
-
};
|
|
1558
|
-
ListItBuffer.prototype.setColumnWidthAll = function(widthForAll) {
|
|
1559
|
-
if (widthForAll != null && !Array.isArray(widthForAll) && typeof widthForAll !== "number") {
|
|
1560
|
-
throw new Error(
|
|
1561
|
-
"widthForAll must be one of a null, an Array or a number"
|
|
1562
|
-
);
|
|
1563
|
-
}
|
|
1564
|
-
if (Array.isArray(widthForAll)) {
|
|
1565
|
-
for (let i = 0; i < widthForAll.length; i++) {
|
|
1566
|
-
const width = widthForAll[i];
|
|
1567
|
-
if (width != void 0 && typeof width !== "number") {
|
|
1568
|
-
throw new Error(
|
|
1569
|
-
`widthForAll[${i}] must be an undefined or a number`
|
|
1570
|
-
);
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
}
|
|
1574
|
-
this.columnWidth = widthForAll;
|
|
1575
|
-
return this;
|
|
1576
|
-
};
|
|
1577
|
-
ListItBuffer.prototype.getColumnWidth = function(indexOfColumns) {
|
|
1578
|
-
if (Array.isArray(this.columnWidth)) {
|
|
1579
|
-
return this.columnWidth[indexOfColumns];
|
|
1580
|
-
}
|
|
1581
|
-
return this.columnWidth;
|
|
1582
|
-
};
|
|
1583
|
-
ListItBuffer.prototype.setHeaderRow = function(header) {
|
|
1584
|
-
if (header && !Array.isArray(header)) {
|
|
1585
|
-
throw new Error([
|
|
1586
|
-
"The header must be an array,",
|
|
1587
|
-
`but ${typeof header} was specified.`,
|
|
1588
|
-
`header: ${JSON.stringify(header)}`
|
|
1589
|
-
].join(" "));
|
|
1590
|
-
}
|
|
1591
|
-
this.header = header;
|
|
1592
|
-
if (this.header == null) {
|
|
1593
|
-
this.columns.forEach((column) => column.setHeader(null));
|
|
1594
|
-
} else {
|
|
1595
|
-
this.header.forEach((headerText, iCol) => {
|
|
1596
|
-
if (iCol >= this.columns.length) {
|
|
1597
|
-
this.addColumn(headerText);
|
|
1598
|
-
}
|
|
1599
|
-
});
|
|
1600
|
-
}
|
|
1601
|
-
return this;
|
|
1602
|
-
};
|
|
1603
|
-
ListItBuffer.prototype.addColumn = function(headerText) {
|
|
1604
|
-
const column = new Column();
|
|
1605
|
-
if (headerText) {
|
|
1606
|
-
column.setHeader(headerText);
|
|
1607
|
-
}
|
|
1608
|
-
if (this.opt.autoAlign) {
|
|
1609
|
-
column.setAutoAlign(true);
|
|
1610
|
-
}
|
|
1611
|
-
this.columns.push(column);
|
|
1612
|
-
};
|
|
1613
|
-
}
|
|
1614
|
-
});
|
|
1615
|
-
|
|
1616
|
-
// ../../node_modules/list-it/index.js
|
|
1617
|
-
var require_list_it = __commonJS({
|
|
1618
|
-
"../../node_modules/list-it/index.js"(exports2, module2) {
|
|
1619
|
-
"use strict";
|
|
1620
|
-
var ListItBuffer = require_list_it_buffer();
|
|
1621
|
-
function ListIt2(opt) {
|
|
1622
|
-
ListItBuffer.call(this, opt);
|
|
1623
|
-
}
|
|
1624
|
-
ListIt2.prototype = new ListItBuffer();
|
|
1625
|
-
ListIt2.buffer = function(opt) {
|
|
1626
|
-
opt = opt || {};
|
|
1627
|
-
if (!("autoAlign" in opt)) {
|
|
1628
|
-
opt.autoAlign = false;
|
|
1629
|
-
}
|
|
1630
|
-
return new ListIt2(opt);
|
|
1631
|
-
};
|
|
1632
|
-
module2.exports = ListIt2;
|
|
1633
|
-
}
|
|
1634
|
-
});
|
|
1635
|
-
|
|
1636
30
|
// src/scripts/signals.ts
|
|
1637
31
|
var signals_exports = {};
|
|
1638
32
|
__export(signals_exports, {
|
|
@@ -1645,25 +39,26 @@ __export(signals_exports, {
|
|
|
1645
39
|
module.exports = __toCommonJS(signals_exports);
|
|
1646
40
|
var import_config = require("dotenv/config");
|
|
1647
41
|
var import_args = __toESM(require("args"));
|
|
42
|
+
|
|
43
|
+
// src/lib/signals/runner.ts
|
|
1648
44
|
var import_progress4 = __toESM(require("progress"));
|
|
1649
45
|
var import_chalk7 = __toESM(require("chalk"));
|
|
1650
46
|
var import_connectors6 = require("@tradejs/node/connectors");
|
|
1651
47
|
var import_cli2 = require("@tradejs/node/cli");
|
|
1652
48
|
var import_async3 = require("@tradejs/core/async");
|
|
1653
|
-
var
|
|
49
|
+
var import_strategies6 = require("@tradejs/core/strategies");
|
|
1654
50
|
var import_constants3 = require("@tradejs/core/constants");
|
|
1655
|
-
var import_strategies6 = require("@tradejs/node/strategies");
|
|
1656
51
|
var import_time3 = require("@tradejs/core/time");
|
|
1657
|
-
var
|
|
1658
|
-
var
|
|
52
|
+
var import_logger5 = require("@tradejs/infra/logger");
|
|
53
|
+
var import_runtimeDeployments = require("@tradejs/infra/runtimeDeployments");
|
|
1659
54
|
|
|
1660
55
|
// src/lib/marketData/windows.ts
|
|
1661
56
|
var import_indicators = require("@tradejs/core/indicators");
|
|
1662
|
-
var resolveOpenTimestamp = (timestamp,
|
|
1663
|
-
var getClosedCandlesForInterval = (candles, currentTimestamp,
|
|
57
|
+
var resolveOpenTimestamp = (timestamp, intervalMs) => Number.isFinite(intervalMs) && intervalMs > 0 ? Math.floor(timestamp / intervalMs) * intervalMs : timestamp;
|
|
58
|
+
var getClosedCandlesForInterval = (candles, currentTimestamp, intervalMs) => {
|
|
1664
59
|
const currentOpenTimestamp = resolveOpenTimestamp(
|
|
1665
60
|
currentTimestamp,
|
|
1666
|
-
|
|
61
|
+
intervalMs
|
|
1667
62
|
);
|
|
1668
63
|
return candles.filter((candle) => candle.timestamp < currentOpenTimestamp);
|
|
1669
64
|
};
|
|
@@ -1671,7 +66,7 @@ var alignSymbolWithBtcReference = (symbolCandles, btcCandles) => (0, import_indi
|
|
|
1671
66
|
|
|
1672
67
|
// src/lib/runFormatting.ts
|
|
1673
68
|
var import_date_fns = require("date-fns");
|
|
1674
|
-
var ListIt =
|
|
69
|
+
var ListIt = require("list-it");
|
|
1675
70
|
var formatDuration = (startedAt) => {
|
|
1676
71
|
const seconds = Math.max(0, (Date.now() - startedAt) / 1e3);
|
|
1677
72
|
if (seconds < 60) return `${seconds.toFixed(1)}s`;
|
|
@@ -1716,7 +111,7 @@ var invokeAfterSignalsHooks = async (hooks, params) => {
|
|
|
1716
111
|
|
|
1717
112
|
// src/lib/marketContextPrepare.ts
|
|
1718
113
|
var import_chalk4 = __toESM(require("chalk"));
|
|
1719
|
-
var
|
|
114
|
+
var import_marketContext3 = require("@tradejs/infra/timescale/marketContext");
|
|
1720
115
|
var import_registry = require("@tradejs/node/registry");
|
|
1721
116
|
|
|
1722
117
|
// src/lib/binanceMarketContextBackfill.ts
|
|
@@ -1725,7 +120,8 @@ var import_chalk = __toESM(require("chalk"));
|
|
|
1725
120
|
var import_connectors = require("@tradejs/connectors");
|
|
1726
121
|
var import_connectors2 = require("@tradejs/node/connectors");
|
|
1727
122
|
var import_strategies = require("@tradejs/node/strategies");
|
|
1728
|
-
var
|
|
123
|
+
var import_marketContext = require("@tradejs/infra/timescale/marketContext");
|
|
124
|
+
var import_client = require("@tradejs/infra/timescale/client");
|
|
1729
125
|
|
|
1730
126
|
// src/lib/binanceMarketData.ts
|
|
1731
127
|
var MARKET_FEATURE_INTERVAL_MS = {
|
|
@@ -1779,17 +175,17 @@ var classifyBtcAltRegime = ({
|
|
|
1779
175
|
};
|
|
1780
176
|
var aggregateAggTradesToRows = ({
|
|
1781
177
|
symbol,
|
|
1782
|
-
interval
|
|
178
|
+
interval,
|
|
1783
179
|
trades,
|
|
1784
180
|
source = "binance_agg_trades"
|
|
1785
181
|
}) => {
|
|
1786
|
-
const
|
|
182
|
+
const intervalMs = MARKET_FEATURE_INTERVAL_MS[interval];
|
|
1787
183
|
const buckets = /* @__PURE__ */ new Map();
|
|
1788
184
|
for (const trade of trades) {
|
|
1789
|
-
const bucketTs = Math.floor(trade.timestamp /
|
|
185
|
+
const bucketTs = Math.floor(trade.timestamp / intervalMs) * intervalMs;
|
|
1790
186
|
const row = buckets.get(bucketTs) ?? {
|
|
1791
187
|
symbol,
|
|
1792
|
-
interval
|
|
188
|
+
interval,
|
|
1793
189
|
ts: new Date(bucketTs),
|
|
1794
190
|
trades: 0,
|
|
1795
191
|
buyBaseVolume: 0,
|
|
@@ -1823,7 +219,7 @@ var aggregateAggTradesToRows = ({
|
|
|
1823
219
|
};
|
|
1824
220
|
var buildKlineTradeFlowRows = ({
|
|
1825
221
|
symbol,
|
|
1826
|
-
interval
|
|
222
|
+
interval,
|
|
1827
223
|
candles,
|
|
1828
224
|
source = "binance_klines"
|
|
1829
225
|
}) => candles.map((candle) => {
|
|
@@ -1837,7 +233,7 @@ var buildKlineTradeFlowRows = ({
|
|
|
1837
233
|
const trades = candle.trades != null && Number.isFinite(candle.trades) ? Math.max(0, Math.trunc(candle.trades)) : 0;
|
|
1838
234
|
return {
|
|
1839
235
|
symbol,
|
|
1840
|
-
interval
|
|
236
|
+
interval,
|
|
1841
237
|
ts: new Date(candle.timestamp),
|
|
1842
238
|
trades,
|
|
1843
239
|
buyBaseVolume,
|
|
@@ -1855,7 +251,7 @@ var buildKlineTradeFlowRows = ({
|
|
|
1855
251
|
}).filter((row) => row != null);
|
|
1856
252
|
var buildMarketBreadthRows = ({
|
|
1857
253
|
universe,
|
|
1858
|
-
interval
|
|
254
|
+
interval,
|
|
1859
255
|
candlesBySymbol,
|
|
1860
256
|
btcCandles,
|
|
1861
257
|
source = "binance_klines"
|
|
@@ -1880,10 +276,10 @@ var buildMarketBreadthRows = ({
|
|
|
1880
276
|
btcCandles.map((candle) => Math.max(0, candle.turnover ?? 0))
|
|
1881
277
|
)
|
|
1882
278
|
} : null;
|
|
1883
|
-
const
|
|
1884
|
-
const bars1h = Math.max(1, Math.round(36e5 /
|
|
1885
|
-
const bars4h = Math.max(1, Math.round(144e5 /
|
|
1886
|
-
const bars24h = Math.max(1, Math.round(864e5 /
|
|
279
|
+
const intervalMs = MARKET_FEATURE_INTERVAL_MS[interval];
|
|
280
|
+
const bars1h = Math.max(1, Math.round(36e5 / intervalMs));
|
|
281
|
+
const bars4h = Math.max(1, Math.round(144e5 / intervalMs));
|
|
282
|
+
const bars24h = Math.max(1, Math.round(864e5 / intervalMs));
|
|
1887
283
|
for (const candles of Object.values(candlesBySymbol)) {
|
|
1888
284
|
for (const candle of candles) timestamps.add(candle.timestamp);
|
|
1889
285
|
}
|
|
@@ -1994,7 +390,7 @@ var buildMarketBreadthRows = ({
|
|
|
1994
390
|
const btcTurnoverShareChange24h = btcTurnoverShare24h == null || previousBtcTurnoverShare24h == null ? null : btcTurnoverShare24h - previousBtcTurnoverShare24h;
|
|
1995
391
|
return {
|
|
1996
392
|
universe,
|
|
1997
|
-
interval
|
|
393
|
+
interval,
|
|
1998
394
|
ts: new Date(timestamp),
|
|
1999
395
|
symbolsCount: returns.length,
|
|
2000
396
|
advancers,
|
|
@@ -2055,17 +451,17 @@ var getReferenceSymbols = () => {
|
|
|
2055
451
|
const symbols = (process.env.BINANCE_MARKET_CONTEXT_REFERENCE_SYMBOLS || "BTCUSDT,ETHUSDT").split(",").map((item) => item.trim().toUpperCase()).filter(Boolean);
|
|
2056
452
|
return symbols.length ? [...new Set(symbols)] : ["BTCUSDT", "ETHUSDT"];
|
|
2057
453
|
};
|
|
2058
|
-
var intervalToMarketFeatureInterval = (
|
|
2059
|
-
const normalized = String(
|
|
454
|
+
var intervalToMarketFeatureInterval = (interval) => {
|
|
455
|
+
const normalized = String(interval).trim().toLowerCase();
|
|
2060
456
|
if (normalized === "1" || normalized === "1m") return "1m";
|
|
2061
457
|
if (normalized === "5" || normalized === "5m") return "5m";
|
|
2062
458
|
if (normalized === "60" || normalized === "1h") return "1h";
|
|
2063
459
|
return "15m";
|
|
2064
460
|
};
|
|
2065
|
-
var marketIntervalToConnectorInterval = (
|
|
2066
|
-
if (
|
|
2067
|
-
if (
|
|
2068
|
-
if (
|
|
461
|
+
var marketIntervalToConnectorInterval = (interval) => {
|
|
462
|
+
if (interval === "1m") return "1";
|
|
463
|
+
if (interval === "5m") return "5";
|
|
464
|
+
if (interval === "1h") return "60";
|
|
2069
465
|
return "15";
|
|
2070
466
|
};
|
|
2071
467
|
var resolveBinanceMarketContextBackfillWindow = ({
|
|
@@ -2088,21 +484,21 @@ var hasCoverage = ({
|
|
|
2088
484
|
coverage,
|
|
2089
485
|
startMs,
|
|
2090
486
|
endMs,
|
|
2091
|
-
intervalMs
|
|
487
|
+
intervalMs
|
|
2092
488
|
}) => {
|
|
2093
489
|
if (!coverage) return false;
|
|
2094
|
-
const expectedRows = Math.max(1, Math.floor((endMs - startMs) /
|
|
2095
|
-
return coverage.firstMs <= startMs +
|
|
490
|
+
const expectedRows = Math.max(1, Math.floor((endMs - startMs) / intervalMs));
|
|
491
|
+
return coverage.firstMs <= startMs + intervalMs && coverage.lastMs >= endMs - intervalMs && coverage.rows >= Math.floor(expectedRows * 0.9);
|
|
2096
492
|
};
|
|
2097
493
|
var buildBreadthBackfillChunks = ({
|
|
2098
494
|
startMs,
|
|
2099
495
|
endMs,
|
|
2100
|
-
intervalMs
|
|
496
|
+
intervalMs,
|
|
2101
497
|
chunkDays
|
|
2102
498
|
}) => {
|
|
2103
|
-
const chunkMs = Math.max(
|
|
2104
|
-
const warmupBars = Math.max(50, Math.ceil(DAY_MS * 2 /
|
|
2105
|
-
const warmupMs = warmupBars *
|
|
499
|
+
const chunkMs = Math.max(intervalMs, chunkDays * DAY_MS);
|
|
500
|
+
const warmupBars = Math.max(50, Math.ceil(DAY_MS * 2 / intervalMs));
|
|
501
|
+
const warmupMs = warmupBars * intervalMs;
|
|
2106
502
|
const chunks = [];
|
|
2107
503
|
let cursor = startMs;
|
|
2108
504
|
while (cursor <= endMs) {
|
|
@@ -2119,10 +515,10 @@ var buildBreadthBackfillChunks = ({
|
|
|
2119
515
|
var buildTradeFlowBackfillChunks = ({
|
|
2120
516
|
startMs,
|
|
2121
517
|
endMs,
|
|
2122
|
-
intervalMs
|
|
518
|
+
intervalMs,
|
|
2123
519
|
chunkDays
|
|
2124
520
|
}) => {
|
|
2125
|
-
const chunkMs = Math.max(
|
|
521
|
+
const chunkMs = Math.max(intervalMs, chunkDays * DAY_MS);
|
|
2126
522
|
const chunks = [];
|
|
2127
523
|
let cursor = startMs;
|
|
2128
524
|
while (cursor <= endMs) {
|
|
@@ -2135,13 +531,13 @@ var buildTradeFlowBackfillChunks = ({
|
|
|
2135
531
|
var filterMissingBreadthBackfillChunks = ({
|
|
2136
532
|
chunks,
|
|
2137
533
|
coverage,
|
|
2138
|
-
intervalMs
|
|
534
|
+
intervalMs
|
|
2139
535
|
}) => chunks.filter(
|
|
2140
536
|
(chunk) => !hasCoverage({
|
|
2141
537
|
coverage,
|
|
2142
538
|
startMs: chunk.startMs,
|
|
2143
539
|
endMs: chunk.endMs,
|
|
2144
|
-
intervalMs
|
|
540
|
+
intervalMs
|
|
2145
541
|
})
|
|
2146
542
|
);
|
|
2147
543
|
var fetchAggTradesForWindow = async ({
|
|
@@ -2181,12 +577,12 @@ var fetchAggTradesForWindow = async ({
|
|
|
2181
577
|
return rows;
|
|
2182
578
|
};
|
|
2183
579
|
var getBinanceConnector = async ({
|
|
2184
|
-
projectRoot
|
|
580
|
+
projectRoot,
|
|
2185
581
|
userName
|
|
2186
582
|
}) => {
|
|
2187
583
|
const creator = await (0, import_connectors2.getConnectorCreatorByName)(
|
|
2188
584
|
import_connectors.ConnectorNames.Binance,
|
|
2189
|
-
|
|
585
|
+
projectRoot
|
|
2190
586
|
);
|
|
2191
587
|
if (!creator) {
|
|
2192
588
|
throw new Error(
|
|
@@ -2227,13 +623,13 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2227
623
|
if (!enabled || !symbols.length) {
|
|
2228
624
|
return skippedBackfillResult();
|
|
2229
625
|
}
|
|
2230
|
-
const
|
|
2231
|
-
const
|
|
626
|
+
const interval = intervalToMarketFeatureInterval(params.interval);
|
|
627
|
+
const intervalMs = MARKET_FEATURE_INTERVAL_MS[interval];
|
|
2232
628
|
const { breadthStartMs, tradeFlowStartMs, endMs } = resolveBinanceMarketContextBackfillWindow(params);
|
|
2233
629
|
if (endMs <= Math.min(breadthStartMs, tradeFlowStartMs)) {
|
|
2234
630
|
return skippedBackfillResult();
|
|
2235
631
|
}
|
|
2236
|
-
await (0,
|
|
632
|
+
await (0, import_client.waitForDbReady)();
|
|
2237
633
|
const connector = await getBinanceConnector({
|
|
2238
634
|
projectRoot: params.projectRoot,
|
|
2239
635
|
userName: params.userName
|
|
@@ -2275,13 +671,13 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2275
671
|
let breadthRows = 0;
|
|
2276
672
|
console.log(
|
|
2277
673
|
import_chalk.default.cyan(
|
|
2278
|
-
`binance market context backfill: requestedSymbols=${symbols.length}, referenceSymbols=${referenceSymbols.length}, interval=${
|
|
674
|
+
`binance market context backfill: requestedSymbols=${symbols.length}, referenceSymbols=${referenceSymbols.length}, interval=${interval}, tradeFlowWindow=${new Date(tradeFlowStartMs).toISOString()}..${new Date(endMs).toISOString()}, breadthWindow=${new Date(breadthStartMs).toISOString()}..${new Date(endMs).toISOString()}`
|
|
2279
675
|
)
|
|
2280
676
|
);
|
|
2281
677
|
if (includeTradeFlow && referenceSymbols.length) {
|
|
2282
|
-
const coverage = await (0,
|
|
678
|
+
const coverage = await (0, import_marketContext.getMarketTradeFlowCoverage)({
|
|
2283
679
|
symbols: referenceSymbols,
|
|
2284
|
-
interval
|
|
680
|
+
interval,
|
|
2285
681
|
startMs: tradeFlowStartMs,
|
|
2286
682
|
endMs
|
|
2287
683
|
});
|
|
@@ -2290,7 +686,7 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2290
686
|
coverage: coverage.get(symbol),
|
|
2291
687
|
startMs: tradeFlowStartMs,
|
|
2292
688
|
endMs,
|
|
2293
|
-
intervalMs
|
|
689
|
+
intervalMs
|
|
2294
690
|
})
|
|
2295
691
|
);
|
|
2296
692
|
const bar = new import_progress.default(
|
|
@@ -2303,11 +699,11 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2303
699
|
if (!missingSymbols.length) {
|
|
2304
700
|
bar.tick(1, { rows: 0, skip: referenceSymbols.length, symbol: "cached" });
|
|
2305
701
|
}
|
|
2306
|
-
const connectorInterval = marketIntervalToConnectorInterval(
|
|
702
|
+
const connectorInterval = marketIntervalToConnectorInterval(interval);
|
|
2307
703
|
const chunks = buildTradeFlowBackfillChunks({
|
|
2308
704
|
startMs: tradeFlowStartMs,
|
|
2309
705
|
endMs,
|
|
2310
|
-
intervalMs
|
|
706
|
+
intervalMs,
|
|
2311
707
|
chunkDays: tradeFlowChunkDays
|
|
2312
708
|
});
|
|
2313
709
|
const chunkBar = missingSymbols.length ? new import_progress.default(
|
|
@@ -2326,7 +722,7 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2326
722
|
coverage: symbolCoverage,
|
|
2327
723
|
startMs: chunk.startMs,
|
|
2328
724
|
endMs: chunk.endMs,
|
|
2329
|
-
intervalMs
|
|
725
|
+
intervalMs
|
|
2330
726
|
})) {
|
|
2331
727
|
skippedTradeFlowChunks += 1;
|
|
2332
728
|
chunkBar?.tick(1, {
|
|
@@ -2339,7 +735,7 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2339
735
|
}
|
|
2340
736
|
const rows = tradeFlowSource === "agg_trades" ? aggregateAggTradesToRows({
|
|
2341
737
|
symbol,
|
|
2342
|
-
interval
|
|
738
|
+
interval,
|
|
2343
739
|
trades: await fetchAggTradesForWindow({
|
|
2344
740
|
connector,
|
|
2345
741
|
symbol,
|
|
@@ -2350,7 +746,7 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2350
746
|
})
|
|
2351
747
|
}) : buildKlineTradeFlowRows({
|
|
2352
748
|
symbol,
|
|
2353
|
-
interval
|
|
749
|
+
interval,
|
|
2354
750
|
candles: await connector.kline({
|
|
2355
751
|
symbol,
|
|
2356
752
|
interval: connectorInterval,
|
|
@@ -2363,7 +759,7 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2363
759
|
const ts = row.ts.getTime();
|
|
2364
760
|
return ts >= chunk.startMs && ts <= chunk.endMs;
|
|
2365
761
|
});
|
|
2366
|
-
await (0,
|
|
762
|
+
await (0, import_marketContext.upsertMarketTradeFlowRows)(boundedRows);
|
|
2367
763
|
tradeFlowRows += boundedRows.length;
|
|
2368
764
|
chunkBar?.tick(1, {
|
|
2369
765
|
rows: tradeFlowRows,
|
|
@@ -2382,18 +778,18 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2382
778
|
if (includeBreadth) {
|
|
2383
779
|
const breadthUniverses = (0, import_strategies.getBinanceBreadthUniverses)();
|
|
2384
780
|
const breadthSymbols = breadthUniverses.at(-1)?.symbols ?? [];
|
|
2385
|
-
const connectorInterval = marketIntervalToConnectorInterval(
|
|
781
|
+
const connectorInterval = marketIntervalToConnectorInterval(interval);
|
|
2386
782
|
const chunks = buildBreadthBackfillChunks({
|
|
2387
783
|
startMs: breadthStartMs,
|
|
2388
784
|
endMs,
|
|
2389
|
-
intervalMs
|
|
785
|
+
intervalMs,
|
|
2390
786
|
chunkDays: breadthChunkDays
|
|
2391
787
|
});
|
|
2392
788
|
const plans = await Promise.all(
|
|
2393
789
|
breadthUniverses.map(async (definition) => {
|
|
2394
|
-
const coverage = await (0,
|
|
790
|
+
const coverage = await (0, import_marketContext.getMarketBreadthCoverage)({
|
|
2395
791
|
universe: definition.universe,
|
|
2396
|
-
interval
|
|
792
|
+
interval,
|
|
2397
793
|
startMs: breadthStartMs,
|
|
2398
794
|
endMs
|
|
2399
795
|
});
|
|
@@ -2402,11 +798,11 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2402
798
|
coverage,
|
|
2403
799
|
startMs: breadthStartMs,
|
|
2404
800
|
endMs,
|
|
2405
|
-
intervalMs
|
|
801
|
+
intervalMs
|
|
2406
802
|
}) || !hasBtcAltMetrics ? !hasBtcAltMetrics ? chunks : filterMissingBreadthBackfillChunks({
|
|
2407
803
|
chunks,
|
|
2408
804
|
coverage,
|
|
2409
|
-
intervalMs
|
|
805
|
+
intervalMs
|
|
2410
806
|
}) : [];
|
|
2411
807
|
if (!missingChunks2.length) {
|
|
2412
808
|
console.log(
|
|
@@ -2485,14 +881,14 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2485
881
|
);
|
|
2486
882
|
const rows = buildMarketBreadthRows({
|
|
2487
883
|
universe: plan.definition.universe,
|
|
2488
|
-
interval
|
|
884
|
+
interval,
|
|
2489
885
|
candlesBySymbol: universeCandles,
|
|
2490
886
|
btcCandles
|
|
2491
887
|
}).filter((row) => {
|
|
2492
888
|
const ts = row.ts.getTime();
|
|
2493
889
|
return ts >= chunk.startMs && ts <= chunk.endMs;
|
|
2494
890
|
});
|
|
2495
|
-
await (0,
|
|
891
|
+
await (0, import_marketContext.upsertMarketBreadthRows)(rows);
|
|
2496
892
|
breadthRows += rows.length;
|
|
2497
893
|
}
|
|
2498
894
|
}
|
|
@@ -2520,7 +916,8 @@ var import_progress2 = __toESM(require("progress"));
|
|
|
2520
916
|
var import_async = require("@tradejs/core/async");
|
|
2521
917
|
var import_constants = require("@tradejs/core/constants");
|
|
2522
918
|
var import_indicators2 = require("@tradejs/core/indicators");
|
|
2523
|
-
var
|
|
919
|
+
var import_derivatives = require("@tradejs/infra/timescale/derivatives");
|
|
920
|
+
var import_client2 = require("@tradejs/infra/timescale/client");
|
|
2524
921
|
var import_userSettings = require("@tradejs/infra/userSettings");
|
|
2525
922
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
2526
923
|
var DAY_MS2 = 24 * HOUR_MS;
|
|
@@ -2530,7 +927,7 @@ var coinalyzeIntervalMap = {
|
|
|
2530
927
|
"15m": "15min",
|
|
2531
928
|
"1h": "1hour"
|
|
2532
929
|
};
|
|
2533
|
-
var derivativesIntervalMs = (
|
|
930
|
+
var derivativesIntervalMs = (interval) => interval === "1h" ? HOUR_MS : 15 * 60 * 1e3;
|
|
2534
931
|
var lastRequestTs = 0;
|
|
2535
932
|
var asInt2 = (value, fallback) => {
|
|
2536
933
|
const parsed = Number.parseInt(String(value ?? ""), 10);
|
|
@@ -2620,12 +1017,12 @@ var resolveDerivativesContextBackfillWindow = (params) => {
|
|
|
2620
1017
|
};
|
|
2621
1018
|
};
|
|
2622
1019
|
var resolveDerivativesContextIntervalBackfillWindow = (params) => {
|
|
2623
|
-
const
|
|
2624
|
-
const alignedToMs = params.closedOnly ? (0, import_indicators2.getLastClosedDerivativesBarStartMs)(params.toMs, params.interval) : Math.floor(params.toMs /
|
|
1020
|
+
const intervalMs = derivativesIntervalMs(params.interval);
|
|
1021
|
+
const alignedToMs = params.closedOnly ? (0, import_indicators2.getLastClosedDerivativesBarStartMs)(params.toMs, params.interval) : Math.floor(params.toMs / intervalMs) * intervalMs;
|
|
2625
1022
|
return {
|
|
2626
|
-
fromMs: Math.floor(params.fromMs /
|
|
1023
|
+
fromMs: Math.floor(params.fromMs / intervalMs) * intervalMs,
|
|
2627
1024
|
toMs: alignedToMs,
|
|
2628
|
-
intervalMs
|
|
1025
|
+
intervalMs
|
|
2629
1026
|
};
|
|
2630
1027
|
};
|
|
2631
1028
|
var resolveDerivativesContextMissingFetchFromMs = (params) => {
|
|
@@ -2974,10 +1371,10 @@ var toSeriesMap = (raw, metric) => {
|
|
|
2974
1371
|
return out;
|
|
2975
1372
|
};
|
|
2976
1373
|
var fetchMetricBatch = async (params) => {
|
|
2977
|
-
const { endpoint, metric, marketSymbols, apiKey, interval
|
|
1374
|
+
const { endpoint, metric, marketSymbols, apiKey, interval, fromMs, toMs } = params;
|
|
2978
1375
|
const url = new URL(`${getCoinalyzeBaseUrl()}${endpoint}`);
|
|
2979
1376
|
url.searchParams.set("symbols", marketSymbols.join(","));
|
|
2980
|
-
url.searchParams.set("interval", coinalyzeIntervalMap[
|
|
1377
|
+
url.searchParams.set("interval", coinalyzeIntervalMap[interval] || interval);
|
|
2981
1378
|
url.searchParams.set("from", String(Math.floor(fromMs / 1e3)));
|
|
2982
1379
|
url.searchParams.set("to", String(Math.floor(toMs / 1e3)));
|
|
2983
1380
|
const raw = await fetchJsonWithRateLimit(url.toString(), apiKey);
|
|
@@ -3021,25 +1418,25 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3021
1418
|
30
|
|
3022
1419
|
);
|
|
3023
1420
|
const batchMs = batchDays * DAY_MS2;
|
|
3024
|
-
const intervalWindows = intervals.map((
|
|
3025
|
-
interval
|
|
1421
|
+
const intervalWindows = intervals.map((interval) => ({
|
|
1422
|
+
interval,
|
|
3026
1423
|
...resolveDerivativesContextIntervalBackfillWindow({
|
|
3027
1424
|
fromMs,
|
|
3028
1425
|
toMs: safeEndMs,
|
|
3029
|
-
interval
|
|
1426
|
+
interval,
|
|
3030
1427
|
closedOnly: mode === "signals"
|
|
3031
1428
|
})
|
|
3032
1429
|
})).filter((item) => item.toMs > item.fromMs);
|
|
3033
1430
|
if (!intervalWindows.length) {
|
|
3034
1431
|
return skippedBackfillResult2();
|
|
3035
1432
|
}
|
|
3036
|
-
await (0,
|
|
1433
|
+
await (0, import_client2.waitForDbReady)();
|
|
3037
1434
|
const edgesByInterval = /* @__PURE__ */ new Map();
|
|
3038
1435
|
await Promise.all(
|
|
3039
|
-
intervalWindows.map(async ({ interval
|
|
1436
|
+
intervalWindows.map(async ({ interval }) => {
|
|
3040
1437
|
edgesByInterval.set(
|
|
3041
|
-
|
|
3042
|
-
await (0,
|
|
1438
|
+
interval,
|
|
1439
|
+
await (0, import_derivatives.getDerivativesDataEdgesForSymbols)(symbols, interval)
|
|
3043
1440
|
);
|
|
3044
1441
|
})
|
|
3045
1442
|
);
|
|
@@ -3048,32 +1445,32 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3048
1445
|
const liquidationCoverageRangesByInterval = /* @__PURE__ */ new Map();
|
|
3049
1446
|
const coverageNowMs = Date.now();
|
|
3050
1447
|
await Promise.all(
|
|
3051
|
-
intervalWindows.map(async (
|
|
1448
|
+
intervalWindows.map(async (window) => {
|
|
3052
1449
|
const confirmedLiquidationWindow = (0, import_indicators2.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3053
|
-
interval:
|
|
3054
|
-
fromMs:
|
|
3055
|
-
toMs:
|
|
1450
|
+
interval: window.interval,
|
|
1451
|
+
fromMs: window.fromMs,
|
|
1452
|
+
toMs: window.toMs,
|
|
3056
1453
|
nowMs: coverageNowMs
|
|
3057
1454
|
});
|
|
3058
1455
|
const [coverageRows, liquidationCoverageRows] = await Promise.all([
|
|
3059
|
-
(0,
|
|
1456
|
+
(0, import_derivatives.getDerivativesBackfillCoverage)({
|
|
3060
1457
|
source: "coinalyze",
|
|
3061
1458
|
symbols,
|
|
3062
|
-
interval:
|
|
3063
|
-
fromMs:
|
|
3064
|
-
toMs:
|
|
1459
|
+
interval: window.interval,
|
|
1460
|
+
fromMs: window.fromMs,
|
|
1461
|
+
toMs: window.toMs
|
|
3065
1462
|
}),
|
|
3066
|
-
confirmedLiquidationWindow ? (0,
|
|
1463
|
+
confirmedLiquidationWindow ? (0, import_derivatives.getDerivativesMetricCoverage)({
|
|
3067
1464
|
source: "coinalyze",
|
|
3068
1465
|
metric: "liquidation",
|
|
3069
1466
|
symbols,
|
|
3070
|
-
interval:
|
|
1467
|
+
interval: window.interval,
|
|
3071
1468
|
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3072
1469
|
toMs: confirmedLiquidationWindow.toMs
|
|
3073
1470
|
}) : Promise.resolve([])
|
|
3074
1471
|
]);
|
|
3075
1472
|
coverageKeysByInterval.set(
|
|
3076
|
-
|
|
1473
|
+
window.interval,
|
|
3077
1474
|
new Set(
|
|
3078
1475
|
coverageRows.map(
|
|
3079
1476
|
(row) => coverageKey({
|
|
@@ -3092,7 +1489,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3092
1489
|
ranges.push({ fromMs: row.fromMs, toMs: row.toMs });
|
|
3093
1490
|
rangesBySymbol.set(symbol, ranges);
|
|
3094
1491
|
}
|
|
3095
|
-
coverageRangesByInterval.set(
|
|
1492
|
+
coverageRangesByInterval.set(window.interval, rangesBySymbol);
|
|
3096
1493
|
const liquidationRangesBySymbol = /* @__PURE__ */ new Map();
|
|
3097
1494
|
for (const row of liquidationCoverageRows) {
|
|
3098
1495
|
const symbol = row.symbol.toUpperCase();
|
|
@@ -3101,33 +1498,33 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3101
1498
|
liquidationRangesBySymbol.set(symbol, ranges);
|
|
3102
1499
|
}
|
|
3103
1500
|
liquidationCoverageRangesByInterval.set(
|
|
3104
|
-
|
|
1501
|
+
window.interval,
|
|
3105
1502
|
liquidationRangesBySymbol
|
|
3106
1503
|
);
|
|
3107
1504
|
})
|
|
3108
1505
|
);
|
|
3109
1506
|
const cachedWindows = intervalWindows.reduce(
|
|
3110
|
-
(sum,
|
|
3111
|
-
fromMs:
|
|
3112
|
-
toMs:
|
|
1507
|
+
(sum, window) => sum + countBackfillWindows({
|
|
1508
|
+
fromMs: window.fromMs,
|
|
1509
|
+
toMs: window.toMs,
|
|
3113
1510
|
batchMs,
|
|
3114
|
-
intervalMs:
|
|
1511
|
+
intervalMs: window.intervalMs
|
|
3115
1512
|
}),
|
|
3116
1513
|
0
|
|
3117
1514
|
);
|
|
3118
|
-
const allBackfillWindowsCached = mode !== "signals" && intervalWindows.every((
|
|
3119
|
-
const edgesBySymbol = edgesByInterval.get(
|
|
3120
|
-
const coverageKeys = coverageKeysByInterval.get(
|
|
1515
|
+
const allBackfillWindowsCached = mode !== "signals" && intervalWindows.every((window) => {
|
|
1516
|
+
const edgesBySymbol = edgesByInterval.get(window.interval);
|
|
1517
|
+
const coverageKeys = coverageKeysByInterval.get(window.interval);
|
|
3121
1518
|
const backfillWindows = buildBackfillWindows({
|
|
3122
|
-
fromMs:
|
|
3123
|
-
toMs:
|
|
1519
|
+
fromMs: window.fromMs,
|
|
1520
|
+
toMs: window.toMs,
|
|
3124
1521
|
batchMs,
|
|
3125
|
-
intervalMs:
|
|
1522
|
+
intervalMs: window.intervalMs
|
|
3126
1523
|
});
|
|
3127
1524
|
return symbols.every(
|
|
3128
1525
|
(symbol) => backfillWindows.every((backfillWindow) => {
|
|
3129
1526
|
const normalizedSymbol = symbol.toUpperCase();
|
|
3130
|
-
const coverageRanges = coverageRangesByInterval.get(
|
|
1527
|
+
const coverageRanges = coverageRangesByInterval.get(window.interval)?.get(normalizedSymbol) ?? [];
|
|
3131
1528
|
const dataCovered = hasDerivativesWindowCoverage({
|
|
3132
1529
|
edges: edgesBySymbol?.get(normalizedSymbol),
|
|
3133
1530
|
fromMs: backfillWindow.fromMs,
|
|
@@ -3136,26 +1533,26 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3136
1533
|
ranges: coverageRanges,
|
|
3137
1534
|
fromMs: backfillWindow.fromMs,
|
|
3138
1535
|
toMs: backfillWindow.toMs,
|
|
3139
|
-
intervalMs:
|
|
1536
|
+
intervalMs: window.intervalMs
|
|
3140
1537
|
}) == null || coverageKeys?.has(
|
|
3141
1538
|
coverageKey({
|
|
3142
1539
|
symbol: normalizedSymbol,
|
|
3143
|
-
interval:
|
|
1540
|
+
interval: window.interval,
|
|
3144
1541
|
fromMs: backfillWindow.fromMs,
|
|
3145
1542
|
toMs: backfillWindow.toMs
|
|
3146
1543
|
})
|
|
3147
1544
|
);
|
|
3148
1545
|
const confirmedLiquidationWindow = (0, import_indicators2.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3149
|
-
interval:
|
|
1546
|
+
interval: window.interval,
|
|
3150
1547
|
fromMs: backfillWindow.fromMs,
|
|
3151
1548
|
toMs: backfillWindow.toMs,
|
|
3152
1549
|
nowMs: coverageNowMs
|
|
3153
1550
|
});
|
|
3154
1551
|
const liquidationCovered = confirmedLiquidationWindow == null || resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
3155
|
-
ranges: liquidationCoverageRangesByInterval.get(
|
|
1552
|
+
ranges: liquidationCoverageRangesByInterval.get(window.interval)?.get(normalizedSymbol) ?? [],
|
|
3156
1553
|
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3157
1554
|
toMs: confirmedLiquidationWindow.toMs,
|
|
3158
|
-
intervalMs:
|
|
1555
|
+
intervalMs: window.intervalMs
|
|
3159
1556
|
}) == null;
|
|
3160
1557
|
return dataCovered && liquidationCovered;
|
|
3161
1558
|
})
|
|
@@ -3205,11 +1602,11 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3205
1602
|
);
|
|
3206
1603
|
const symbolBatches = chunkArray(matches, symbolBatchSize);
|
|
3207
1604
|
const windowsPerPair = intervalWindows.reduce(
|
|
3208
|
-
(sum,
|
|
3209
|
-
fromMs:
|
|
3210
|
-
toMs:
|
|
1605
|
+
(sum, window) => sum + countBackfillWindows({
|
|
1606
|
+
fromMs: window.fromMs,
|
|
1607
|
+
toMs: window.toMs,
|
|
3211
1608
|
batchMs,
|
|
3212
|
-
intervalMs:
|
|
1609
|
+
intervalMs: window.intervalMs
|
|
3213
1610
|
}),
|
|
3214
1611
|
0
|
|
3215
1612
|
);
|
|
@@ -3232,30 +1629,30 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3232
1629
|
`derivatives context backfill: symbols=${matches.length}, requestedSymbols=${requestedSymbols.length}, unmatched=${unmatched.length}, intervals=${intervals.join(",")}, window=${new Date(fromMs).toISOString()}..${new Date(safeEndMs).toISOString()}, testStart=${new Date(safeStartMs).toISOString()}`
|
|
3233
1630
|
)
|
|
3234
1631
|
);
|
|
3235
|
-
for (const
|
|
3236
|
-
const { interval
|
|
3237
|
-
const edgesBySymbol = edgesByInterval.get(
|
|
1632
|
+
for (const window of intervalWindows) {
|
|
1633
|
+
const { interval, intervalMs } = window;
|
|
1634
|
+
const edgesBySymbol = edgesByInterval.get(interval) ?? await (0, import_derivatives.getDerivativesDataEdgesForSymbols)(
|
|
3238
1635
|
matches.map((item) => item.symbol),
|
|
3239
|
-
|
|
1636
|
+
interval
|
|
3240
1637
|
);
|
|
3241
|
-
const coverageKeys = coverageKeysByInterval.get(
|
|
3242
|
-
coverageKeysByInterval.set(
|
|
3243
|
-
const coverageRangesBySymbol = coverageRangesByInterval.get(
|
|
3244
|
-
coverageRangesByInterval.set(
|
|
3245
|
-
const liquidationCoverageRangesBySymbol = liquidationCoverageRangesByInterval.get(
|
|
1638
|
+
const coverageKeys = coverageKeysByInterval.get(interval) ?? /* @__PURE__ */ new Set();
|
|
1639
|
+
coverageKeysByInterval.set(interval, coverageKeys);
|
|
1640
|
+
const coverageRangesBySymbol = coverageRangesByInterval.get(interval) ?? /* @__PURE__ */ new Map();
|
|
1641
|
+
coverageRangesByInterval.set(interval, coverageRangesBySymbol);
|
|
1642
|
+
const liquidationCoverageRangesBySymbol = liquidationCoverageRangesByInterval.get(interval) ?? /* @__PURE__ */ new Map();
|
|
3246
1643
|
liquidationCoverageRangesByInterval.set(
|
|
3247
|
-
|
|
1644
|
+
interval,
|
|
3248
1645
|
liquidationCoverageRangesBySymbol
|
|
3249
1646
|
);
|
|
3250
1647
|
for (let batchIdx = 0; batchIdx < symbolBatches.length; batchIdx += 1) {
|
|
3251
1648
|
const batch = symbolBatches[batchIdx];
|
|
3252
|
-
let cursor =
|
|
3253
|
-
while (cursor <
|
|
3254
|
-
const toMs = Math.min(
|
|
1649
|
+
let cursor = window.fromMs;
|
|
1650
|
+
while (cursor < window.toMs) {
|
|
1651
|
+
const toMs = Math.min(window.toMs, cursor + batchMs);
|
|
3255
1652
|
const missingRanges = batch.map((item) => {
|
|
3256
1653
|
const key = coverageKey({
|
|
3257
1654
|
symbol: item.symbol,
|
|
3258
|
-
interval
|
|
1655
|
+
interval,
|
|
3259
1656
|
fromMs: cursor,
|
|
3260
1657
|
toMs
|
|
3261
1658
|
});
|
|
@@ -3263,8 +1660,8 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3263
1660
|
const requiredFromMs = resolveDerivativesContextRequiredFetchFromMs(
|
|
3264
1661
|
{
|
|
3265
1662
|
mode,
|
|
3266
|
-
interval
|
|
3267
|
-
intervalMs
|
|
1663
|
+
interval,
|
|
1664
|
+
intervalMs,
|
|
3268
1665
|
fromMs: cursor,
|
|
3269
1666
|
toMs,
|
|
3270
1667
|
nowMs: coverageNowMs,
|
|
@@ -3309,7 +1706,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3309
1706
|
metric: "oi",
|
|
3310
1707
|
marketSymbols,
|
|
3311
1708
|
apiKey,
|
|
3312
|
-
interval
|
|
1709
|
+
interval,
|
|
3313
1710
|
fromMs: group.fromMs,
|
|
3314
1711
|
toMs
|
|
3315
1712
|
});
|
|
@@ -3318,7 +1715,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3318
1715
|
metric: "funding",
|
|
3319
1716
|
marketSymbols,
|
|
3320
1717
|
apiKey,
|
|
3321
|
-
interval
|
|
1718
|
+
interval,
|
|
3322
1719
|
fromMs: group.fromMs,
|
|
3323
1720
|
toMs
|
|
3324
1721
|
});
|
|
@@ -3327,7 +1724,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3327
1724
|
metric: "liq",
|
|
3328
1725
|
marketSymbols,
|
|
3329
1726
|
apiKey,
|
|
3330
|
-
interval
|
|
1727
|
+
interval,
|
|
3331
1728
|
fromMs: group.fromMs,
|
|
3332
1729
|
toMs
|
|
3333
1730
|
});
|
|
@@ -3339,7 +1736,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3339
1736
|
fundingRaw: fundingMap.get(marketSymbol) ?? [],
|
|
3340
1737
|
liqRaw: liquidationRowsByMarket.get(marketSymbol) ?? []
|
|
3341
1738
|
});
|
|
3342
|
-
return (0, import_indicators2.coinalyzePointsToRows)(points,
|
|
1739
|
+
return (0, import_indicators2.coinalyzePointsToRows)(points, interval, "coinalyze");
|
|
3343
1740
|
});
|
|
3344
1741
|
missingClosedSymbols = mode === "signals" ? getMissingClosedDerivativesSymbols({
|
|
3345
1742
|
symbols: missingBatch.map((item) => item.symbol),
|
|
@@ -3353,15 +1750,15 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3353
1750
|
}
|
|
3354
1751
|
if (missingClosedSymbols.length) {
|
|
3355
1752
|
throw new Error(
|
|
3356
|
-
`Coinalyze closed ${
|
|
1753
|
+
`Coinalyze closed ${interval} bar ${new Date(toMs).toISOString()} unavailable for ${missingClosedSymbols.join(",")}`
|
|
3357
1754
|
);
|
|
3358
1755
|
}
|
|
3359
1756
|
if (rows.length) {
|
|
3360
|
-
await (0,
|
|
1757
|
+
await (0, import_derivatives.upsertDerivatives)(rows);
|
|
3361
1758
|
totalRows += rows.length;
|
|
3362
1759
|
}
|
|
3363
1760
|
const confirmedLiquidationWindow = (0, import_indicators2.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3364
|
-
interval
|
|
1761
|
+
interval,
|
|
3365
1762
|
fromMs: group.fromMs,
|
|
3366
1763
|
toMs,
|
|
3367
1764
|
nowMs: coverageNowMs
|
|
@@ -3379,13 +1776,13 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3379
1776
|
source: "coinalyze",
|
|
3380
1777
|
metric: "liquidation",
|
|
3381
1778
|
symbol: item.symbol,
|
|
3382
|
-
interval
|
|
1779
|
+
interval,
|
|
3383
1780
|
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3384
1781
|
toMs: confirmedLiquidationWindow.toMs,
|
|
3385
1782
|
eventRowsCount
|
|
3386
1783
|
};
|
|
3387
1784
|
});
|
|
3388
|
-
await (0,
|
|
1785
|
+
await (0, import_derivatives.applyDerivativesMetricCoverage)(metricCoverageRows);
|
|
3389
1786
|
for (const coverageRow of metricCoverageRows) {
|
|
3390
1787
|
const symbol = coverageRow.symbol.toUpperCase();
|
|
3391
1788
|
const ranges = liquidationCoverageRangesBySymbol.get(symbol) ?? [];
|
|
@@ -3411,13 +1808,13 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3411
1808
|
return {
|
|
3412
1809
|
source: "coinalyze",
|
|
3413
1810
|
symbol: item.symbol,
|
|
3414
|
-
interval
|
|
1811
|
+
interval,
|
|
3415
1812
|
fromMs: cursor,
|
|
3416
1813
|
toMs,
|
|
3417
1814
|
rowsCount
|
|
3418
1815
|
};
|
|
3419
1816
|
});
|
|
3420
|
-
await (0,
|
|
1817
|
+
await (0, import_derivatives.upsertDerivativesBackfillCoverage)(coverageRows);
|
|
3421
1818
|
for (const coverageRow of coverageRows) {
|
|
3422
1819
|
const symbol = coverageRow.symbol.toUpperCase();
|
|
3423
1820
|
edgesBySymbol.set(
|
|
@@ -3427,7 +1824,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3427
1824
|
coverageKeys.add(
|
|
3428
1825
|
coverageKey({
|
|
3429
1826
|
symbol,
|
|
3430
|
-
interval
|
|
1827
|
+
interval,
|
|
3431
1828
|
fromMs: cursor,
|
|
3432
1829
|
toMs
|
|
3433
1830
|
})
|
|
@@ -3443,20 +1840,20 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3443
1840
|
failedWindows += 1;
|
|
3444
1841
|
console.error(
|
|
3445
1842
|
import_chalk2.default.red(
|
|
3446
|
-
`derivatives context backfill window failed batch=${batchIdx + 1}/${symbolBatches.length} interval=${
|
|
1843
|
+
`derivatives context backfill window failed batch=${batchIdx + 1}/${symbolBatches.length} interval=${interval} ${new Date(cursor).toISOString()}..${new Date(toMs).toISOString()}: ${error}`
|
|
3447
1844
|
)
|
|
3448
1845
|
);
|
|
3449
1846
|
} finally {
|
|
3450
1847
|
bar.tick(1, {
|
|
3451
1848
|
batch: import_chalk2.default.gray(
|
|
3452
|
-
`${batchIdx + 1}/${symbolBatches.length} ${
|
|
1849
|
+
`${batchIdx + 1}/${symbolBatches.length} ${interval}`
|
|
3453
1850
|
),
|
|
3454
1851
|
rows: totalRows,
|
|
3455
1852
|
fail: failedWindows,
|
|
3456
1853
|
skip: skippedWindows
|
|
3457
1854
|
});
|
|
3458
1855
|
}
|
|
3459
|
-
cursor = toMs +
|
|
1856
|
+
cursor = toMs + intervalMs;
|
|
3460
1857
|
}
|
|
3461
1858
|
}
|
|
3462
1859
|
}
|
|
@@ -3494,7 +1891,8 @@ var backfillDerivativesContextForSignals = async (params) => backfillDerivatives
|
|
|
3494
1891
|
// src/lib/coinMarketCapContextBackfill.ts
|
|
3495
1892
|
var import_chalk3 = __toESM(require("chalk"));
|
|
3496
1893
|
var import_async2 = require("@tradejs/core/async");
|
|
3497
|
-
var
|
|
1894
|
+
var import_marketContext2 = require("@tradejs/infra/timescale/marketContext");
|
|
1895
|
+
var import_client3 = require("@tradejs/infra/timescale/client");
|
|
3498
1896
|
var import_userSettings2 = require("@tradejs/infra/userSettings");
|
|
3499
1897
|
var DAY_MS3 = 864e5;
|
|
3500
1898
|
var DEFAULT_CONTEXT_MAX_AGE_MS = 48 * 60 * 6e4;
|
|
@@ -3646,10 +2044,10 @@ var resolveCoinMarketCapBackfillWindow = (params) => {
|
|
|
3646
2044
|
toMs: dayStartUtc(params.endMs)
|
|
3647
2045
|
};
|
|
3648
2046
|
};
|
|
3649
|
-
var hasIntervalCoverage = (coverage, fromMs, toMs,
|
|
2047
|
+
var hasIntervalCoverage = (coverage, fromMs, toMs, intervalMs) => {
|
|
3650
2048
|
if (!coverage) return false;
|
|
3651
|
-
const expectedRows = Math.max(1, Math.floor((toMs - fromMs) /
|
|
3652
|
-
return coverage.firstMs <= fromMs +
|
|
2049
|
+
const expectedRows = Math.max(1, Math.floor((toMs - fromMs) / intervalMs));
|
|
2050
|
+
return coverage.firstMs <= fromMs + intervalMs && coverage.lastMs >= toMs - intervalMs && coverage.rows >= Math.floor(expectedRows * 0.9);
|
|
3653
2051
|
};
|
|
3654
2052
|
var hasDailyCoverage = (coverage, fromMs, toMs) => hasIntervalCoverage(coverage, fromMs, toMs, DAY_MS3);
|
|
3655
2053
|
var coverageKey2 = (params) => [
|
|
@@ -3758,7 +2156,7 @@ var logBackfillSourceDone = (params) => {
|
|
|
3758
2156
|
)
|
|
3759
2157
|
);
|
|
3760
2158
|
};
|
|
3761
|
-
var markBackfillCoverage = (rows) => (0,
|
|
2159
|
+
var markBackfillCoverage = (rows) => (0, import_marketContext2.upsertMarketContextBackfillCoverage)(rows);
|
|
3762
2160
|
var coinMarketCapFetch = async (params) => {
|
|
3763
2161
|
const url = new URL(`${getBaseUrl()}${params.path}`);
|
|
3764
2162
|
for (const [key, value] of Object.entries(params.searchParams)) {
|
|
@@ -3894,7 +2292,7 @@ var normalizeAssetDataItems = (payload) => {
|
|
|
3894
2292
|
}
|
|
3895
2293
|
return [];
|
|
3896
2294
|
};
|
|
3897
|
-
var coinMarketCapHistoricalQuotesPayloadToRows = (payload,
|
|
2295
|
+
var coinMarketCapHistoricalQuotesPayloadToRows = (payload, interval = "1d") => {
|
|
3898
2296
|
return normalizeAssetDataItems(payload).flatMap((asset) => {
|
|
3899
2297
|
const cmcId = toIntOrNull(asset.id);
|
|
3900
2298
|
const symbolRaw = String(asset.symbol ?? "").trim().toUpperCase();
|
|
@@ -3913,7 +2311,7 @@ var coinMarketCapHistoricalQuotesPayloadToRows = (payload, interval2 = "1d") =>
|
|
|
3913
2311
|
source: SOURCE_REFERENCE,
|
|
3914
2312
|
symbol: target.symbol,
|
|
3915
2313
|
cmcId,
|
|
3916
|
-
interval
|
|
2314
|
+
interval,
|
|
3917
2315
|
ts,
|
|
3918
2316
|
openUsd: null,
|
|
3919
2317
|
highUsd: null,
|
|
@@ -3925,7 +2323,7 @@ var coinMarketCapHistoricalQuotesPayloadToRows = (payload, interval2 = "1d") =>
|
|
|
3925
2323
|
}).filter((row) => row != null);
|
|
3926
2324
|
});
|
|
3927
2325
|
};
|
|
3928
|
-
var coinMarketCapExchangeQuotesPayloadToLiquidityRows = (payload,
|
|
2326
|
+
var coinMarketCapExchangeQuotesPayloadToLiquidityRows = (payload, interval = "1d") => {
|
|
3929
2327
|
const data = getRecord(payload).data;
|
|
3930
2328
|
const exchangeItems = Array.isArray(data) ? data : Object.values(getRecord(data));
|
|
3931
2329
|
const rowsByTs = /* @__PURE__ */ new Map();
|
|
@@ -3966,7 +2364,7 @@ var coinMarketCapExchangeQuotesPayloadToLiquidityRows = (payload, interval2 = "1
|
|
|
3966
2364
|
);
|
|
3967
2365
|
return {
|
|
3968
2366
|
source: SOURCE_EXCHANGE_LIQUIDITY,
|
|
3969
|
-
interval
|
|
2367
|
+
interval,
|
|
3970
2368
|
ts: new Date(ts),
|
|
3971
2369
|
exchangesCount: exchanges.length,
|
|
3972
2370
|
totalVolumeUsd,
|
|
@@ -4009,7 +2407,7 @@ var toCmcIndexWeightPct = (value) => {
|
|
|
4009
2407
|
}
|
|
4010
2408
|
return toFiniteNumberOrNull(value);
|
|
4011
2409
|
};
|
|
4012
|
-
var coinMarketCapIndexPayloadToRows = (payload, indexSlug,
|
|
2410
|
+
var coinMarketCapIndexPayloadToRows = (payload, indexSlug, interval = "1d") => {
|
|
4013
2411
|
const data = getRecord(payload).data;
|
|
4014
2412
|
const items = Array.isArray(data) ? data : [];
|
|
4015
2413
|
return items.map((item) => {
|
|
@@ -4038,7 +2436,7 @@ var coinMarketCapIndexPayloadToRows = (payload, indexSlug, interval2 = "1d") =>
|
|
|
4038
2436
|
return {
|
|
4039
2437
|
source: SOURCE_INDEX,
|
|
4040
2438
|
indexSlug,
|
|
4041
|
-
interval
|
|
2439
|
+
interval,
|
|
4042
2440
|
ts,
|
|
4043
2441
|
value,
|
|
4044
2442
|
constituentsCount: constituents.length,
|
|
@@ -4087,7 +2485,7 @@ var backfillCoinMarketCapContext = async (params) => {
|
|
|
4087
2485
|
if (toMs <= fromMs) return skippedResult();
|
|
4088
2486
|
const exchangeLiquidityEnabled = isExchangeLiquidityBackfillEnabled();
|
|
4089
2487
|
const fearGreedEnabled = isFearGreedBackfillEnabled();
|
|
4090
|
-
await (0,
|
|
2488
|
+
await (0, import_client3.waitForDbReady)();
|
|
4091
2489
|
const [
|
|
4092
2490
|
globalDailyCoverage,
|
|
4093
2491
|
referenceDailyCoverage,
|
|
@@ -4100,66 +2498,66 @@ var backfillCoinMarketCapContext = async (params) => {
|
|
|
4100
2498
|
fearGreedBackfillCoverage,
|
|
4101
2499
|
indexBackfillCoverage
|
|
4102
2500
|
] = await Promise.all([
|
|
4103
|
-
(0,
|
|
2501
|
+
(0, import_marketContext2.getMarketGlobalContextCoverage)({
|
|
4104
2502
|
source: SOURCE_GLOBAL_DAILY,
|
|
4105
2503
|
startMs: fromMs,
|
|
4106
2504
|
endMs: toMs
|
|
4107
2505
|
}),
|
|
4108
|
-
(0,
|
|
2506
|
+
(0, import_marketContext2.getMarketReferenceAssetContextCoverage)({
|
|
4109
2507
|
source: SOURCE_REFERENCE,
|
|
4110
2508
|
symbols: REFERENCE_ASSETS.map((item) => item.symbol),
|
|
4111
2509
|
interval: "1d",
|
|
4112
2510
|
startMs: fromMs,
|
|
4113
2511
|
endMs: toMs
|
|
4114
2512
|
}),
|
|
4115
|
-
exchangeLiquidityEnabled ? (0,
|
|
2513
|
+
exchangeLiquidityEnabled ? (0, import_marketContext2.getMarketCmcExchangeLiquidityContextCoverage)({
|
|
4116
2514
|
source: SOURCE_EXCHANGE_LIQUIDITY,
|
|
4117
2515
|
interval: "1d",
|
|
4118
2516
|
startMs: fromMs,
|
|
4119
2517
|
endMs: toMs
|
|
4120
2518
|
}) : Promise.resolve(null),
|
|
4121
|
-
fearGreedEnabled ? (0,
|
|
2519
|
+
fearGreedEnabled ? (0, import_marketContext2.getMarketCmcFearGreedContextCoverage)({
|
|
4122
2520
|
source: SOURCE_FEAR_GREED,
|
|
4123
2521
|
interval: "1d",
|
|
4124
2522
|
startMs: fromMs,
|
|
4125
2523
|
endMs: toMs
|
|
4126
2524
|
}) : Promise.resolve(null),
|
|
4127
|
-
(0,
|
|
2525
|
+
(0, import_marketContext2.getMarketCmcIndexContextCoverage)({
|
|
4128
2526
|
source: SOURCE_INDEX,
|
|
4129
2527
|
indexSlugs: CMC_INDEXES.map((index) => index.slug),
|
|
4130
2528
|
interval: "1d",
|
|
4131
2529
|
startMs: fromMs,
|
|
4132
2530
|
endMs: toMs
|
|
4133
2531
|
}),
|
|
4134
|
-
(0,
|
|
2532
|
+
(0, import_marketContext2.getMarketContextBackfillCoverage)({
|
|
4135
2533
|
source: SOURCE_GLOBAL_DAILY,
|
|
4136
2534
|
scopes: [COVERAGE_SCOPE_ALL],
|
|
4137
2535
|
interval: "1d",
|
|
4138
2536
|
fromMs,
|
|
4139
2537
|
toMs
|
|
4140
2538
|
}),
|
|
4141
|
-
(0,
|
|
2539
|
+
(0, import_marketContext2.getMarketContextBackfillCoverage)({
|
|
4142
2540
|
source: SOURCE_REFERENCE,
|
|
4143
2541
|
scopes: REFERENCE_ASSETS.map((item) => item.symbol),
|
|
4144
2542
|
interval: "1d",
|
|
4145
2543
|
fromMs,
|
|
4146
2544
|
toMs
|
|
4147
2545
|
}),
|
|
4148
|
-
exchangeLiquidityEnabled ? (0,
|
|
2546
|
+
exchangeLiquidityEnabled ? (0, import_marketContext2.getMarketContextBackfillCoverage)({
|
|
4149
2547
|
source: SOURCE_EXCHANGE_LIQUIDITY,
|
|
4150
2548
|
scopes: [COVERAGE_SCOPE_ALL],
|
|
4151
2549
|
interval: "1d",
|
|
4152
2550
|
fromMs,
|
|
4153
2551
|
toMs
|
|
4154
2552
|
}) : Promise.resolve([]),
|
|
4155
|
-
fearGreedEnabled ? (0,
|
|
2553
|
+
fearGreedEnabled ? (0, import_marketContext2.getMarketContextBackfillCoverage)({
|
|
4156
2554
|
source: SOURCE_FEAR_GREED,
|
|
4157
2555
|
scopes: [COVERAGE_SCOPE_ALL],
|
|
4158
2556
|
interval: "1d",
|
|
4159
2557
|
fromMs,
|
|
4160
2558
|
toMs
|
|
4161
2559
|
}) : Promise.resolve([]),
|
|
4162
|
-
(0,
|
|
2560
|
+
(0, import_marketContext2.getMarketContextBackfillCoverage)({
|
|
4163
2561
|
source: SOURCE_INDEX,
|
|
4164
2562
|
scopes: CMC_INDEXES.map((index) => index.slug),
|
|
4165
2563
|
interval: "1d",
|
|
@@ -4350,7 +2748,7 @@ var backfillCoinMarketCapContext = async (params) => {
|
|
|
4350
2748
|
}
|
|
4351
2749
|
});
|
|
4352
2750
|
const rows = coinMarketCapGlobalPayloadToRows(payload, SOURCE_GLOBAL_DAILY);
|
|
4353
|
-
await (0,
|
|
2751
|
+
await (0, import_marketContext2.upsertMarketGlobalContextRows)(rows);
|
|
4354
2752
|
await markBackfillCoverage([
|
|
4355
2753
|
{
|
|
4356
2754
|
source: SOURCE_GLOBAL_DAILY,
|
|
@@ -4384,7 +2782,7 @@ var backfillCoinMarketCapContext = async (params) => {
|
|
|
4384
2782
|
}
|
|
4385
2783
|
});
|
|
4386
2784
|
const rows = coinMarketCapHistoricalQuotesPayloadToRows(payload, "1d");
|
|
4387
|
-
await (0,
|
|
2785
|
+
await (0, import_marketContext2.upsertMarketReferenceAssetContextRows)(rows);
|
|
4388
2786
|
await markBackfillCoverage(
|
|
4389
2787
|
REFERENCE_ASSETS.map((asset) => ({
|
|
4390
2788
|
source: SOURCE_REFERENCE,
|
|
@@ -4423,7 +2821,7 @@ var backfillCoinMarketCapContext = async (params) => {
|
|
|
4423
2821
|
payload,
|
|
4424
2822
|
"1d"
|
|
4425
2823
|
);
|
|
4426
|
-
await (0,
|
|
2824
|
+
await (0, import_marketContext2.upsertMarketCmcExchangeLiquidityContextRows)(rows);
|
|
4427
2825
|
await markBackfillCoverage([
|
|
4428
2826
|
{
|
|
4429
2827
|
source: SOURCE_EXCHANGE_LIQUIDITY,
|
|
@@ -4468,7 +2866,7 @@ var backfillCoinMarketCapContext = async (params) => {
|
|
|
4468
2866
|
const oldestPageTs = Math.min(...pageRows.map((row) => row.ts.getTime()));
|
|
4469
2867
|
if (oldestPageTs < fromMs || pageRows.length < pageSize) break;
|
|
4470
2868
|
}
|
|
4471
|
-
await (0,
|
|
2869
|
+
await (0, import_marketContext2.upsertMarketCmcFearGreedContextRows)(rows);
|
|
4472
2870
|
await markBackfillCoverage([
|
|
4473
2871
|
{
|
|
4474
2872
|
source: SOURCE_FEAR_GREED,
|
|
@@ -4502,7 +2900,7 @@ var backfillCoinMarketCapContext = async (params) => {
|
|
|
4502
2900
|
}))
|
|
4503
2901
|
);
|
|
4504
2902
|
const rows = rowsByIndex.flatMap((item) => item.result.rows);
|
|
4505
|
-
await (0,
|
|
2903
|
+
await (0, import_marketContext2.upsertMarketCmcIndexContextRows)(rows);
|
|
4506
2904
|
await markBackfillCoverage(
|
|
4507
2905
|
rowsByIndex.map(({ index, result }) => ({
|
|
4508
2906
|
source: SOURCE_INDEX,
|
|
@@ -4554,7 +2952,7 @@ var backfillCoinMarketCapContextForSignals = (params) => backfillCoinMarketCapCo
|
|
|
4554
2952
|
|
|
4555
2953
|
// src/lib/hyperliquidWhaleBackfill.ts
|
|
4556
2954
|
var import_progress3 = __toESM(require("progress"));
|
|
4557
|
-
var
|
|
2955
|
+
var import_hyperliquidWhales = require("@tradejs/infra/timescale/hyperliquidWhales");
|
|
4558
2956
|
var import_strategies2 = require("@tradejs/node/strategies");
|
|
4559
2957
|
|
|
4560
2958
|
// src/lib/hyperliquidWhaleData.ts
|
|
@@ -4809,7 +3207,7 @@ var backfillHyperliquidWhaleContext = async (params) => {
|
|
|
4809
3207
|
};
|
|
4810
3208
|
const fromMs = Math.floor(params.startMs / HYPERLIQUID_WHALE_BUCKET_MS) * HYPERLIQUID_WHALE_BUCKET_MS;
|
|
4811
3209
|
const toMs = minuteCeil(params.endMs);
|
|
4812
|
-
const cached = await (0,
|
|
3210
|
+
const cached = await (0, import_hyperliquidWhales.hasHyperliquidWhaleBackfillCoverage)({
|
|
4813
3211
|
fromMs,
|
|
4814
3212
|
toMs,
|
|
4815
3213
|
...identity
|
|
@@ -4858,7 +3256,7 @@ var backfillHyperliquidWhaleContext = async (params) => {
|
|
|
4858
3256
|
items: whales.addresses,
|
|
4859
3257
|
concurrency,
|
|
4860
3258
|
worker: async (address) => {
|
|
4861
|
-
const previous = await (0,
|
|
3259
|
+
const previous = await (0, import_hyperliquidWhales.getHyperliquidWhaleWalletCoverage)({
|
|
4862
3260
|
address,
|
|
4863
3261
|
fromMs,
|
|
4864
3262
|
toMs,
|
|
@@ -4885,8 +3283,8 @@ var backfillHyperliquidWhaleContext = async (params) => {
|
|
|
4885
3283
|
identity
|
|
4886
3284
|
})
|
|
4887
3285
|
).filter((row) => row != null);
|
|
4888
|
-
await (0,
|
|
4889
|
-
await (0,
|
|
3286
|
+
await (0, import_hyperliquidWhales.upsertHyperliquidWhaleTradeEvents)(addressEvents);
|
|
3287
|
+
await (0, import_hyperliquidWhales.upsertHyperliquidWhaleWalletCoverage)({
|
|
4890
3288
|
address,
|
|
4891
3289
|
fromMs,
|
|
4892
3290
|
toMs,
|
|
@@ -4904,7 +3302,7 @@ var backfillHyperliquidWhaleContext = async (params) => {
|
|
|
4904
3302
|
const normalizedError = error instanceof Error ? error : new Error(String(error));
|
|
4905
3303
|
failures.push(normalizedError);
|
|
4906
3304
|
failedWallets += 1;
|
|
4907
|
-
await (0,
|
|
3305
|
+
await (0, import_hyperliquidWhales.upsertHyperliquidWhaleWalletCoverage)({
|
|
4908
3306
|
address,
|
|
4909
3307
|
fromMs,
|
|
4910
3308
|
toMs,
|
|
@@ -4923,7 +3321,7 @@ var backfillHyperliquidWhaleContext = async (params) => {
|
|
|
4923
3321
|
);
|
|
4924
3322
|
}
|
|
4925
3323
|
});
|
|
4926
|
-
const buckets = await (0,
|
|
3324
|
+
const buckets = await (0, import_hyperliquidWhales.rebuildHyperliquidWhaleFlowRows)({
|
|
4927
3325
|
fromMs,
|
|
4928
3326
|
toMs,
|
|
4929
3327
|
...identity
|
|
@@ -4939,7 +3337,7 @@ var backfillHyperliquidWhaleContext = async (params) => {
|
|
|
4939
3337
|
}
|
|
4940
3338
|
);
|
|
4941
3339
|
let displayedCoverageBuckets = 0;
|
|
4942
|
-
const coverageBuckets = await (0,
|
|
3340
|
+
const coverageBuckets = await (0, import_hyperliquidWhales.rebuildHyperliquidWhaleCoverageRows)({
|
|
4943
3341
|
fromMs,
|
|
4944
3342
|
toMs,
|
|
4945
3343
|
expectedWhales: whales.addresses.length,
|
|
@@ -5139,17 +3537,17 @@ var prepareMarketContextForRun = async (params) => {
|
|
|
5139
3537
|
const log = params.log ?? ((message) => {
|
|
5140
3538
|
console.log(import_chalk4.default.gray(message));
|
|
5141
3539
|
});
|
|
5142
|
-
const
|
|
3540
|
+
const timeOperation2 = (label, operation) => timeOperation(label, operation, log);
|
|
5143
3541
|
const requirements = await resolveMarketContextRunRequirements(params);
|
|
5144
3542
|
const readableSources = Object.entries(requirements).filter(([, requirement]) => requirement.read).map(([source]) => source);
|
|
5145
3543
|
if (readableSources.length) {
|
|
5146
|
-
await
|
|
3544
|
+
await timeOperation2(
|
|
5147
3545
|
"market context schema ensure",
|
|
5148
|
-
() => (0,
|
|
3546
|
+
() => (0, import_marketContext3.ensureMarketContextSchemas)(readableSources)
|
|
5149
3547
|
);
|
|
5150
3548
|
}
|
|
5151
3549
|
if (requirements.derivatives.backfill) {
|
|
5152
|
-
await
|
|
3550
|
+
await timeOperation2(
|
|
5153
3551
|
"derivatives context backfill",
|
|
5154
3552
|
() => (params.mode === "signals" ? backfillDerivativesContextForSignals : backfillDerivativesContextForBacktest)(
|
|
5155
3553
|
buildDerivativesBackfillParams(params)
|
|
@@ -5157,7 +3555,7 @@ var prepareMarketContextForRun = async (params) => {
|
|
|
5157
3555
|
);
|
|
5158
3556
|
}
|
|
5159
3557
|
if (requirements.hyperliquidWhales.backfill) {
|
|
5160
|
-
await
|
|
3558
|
+
await timeOperation2(
|
|
5161
3559
|
"hyperliquid whale context backfill",
|
|
5162
3560
|
() => backfillHyperliquidWhaleContext({
|
|
5163
3561
|
startMs: params.preloadStartMs ?? params.startMs,
|
|
@@ -5169,13 +3567,13 @@ var prepareMarketContextForRun = async (params) => {
|
|
|
5169
3567
|
);
|
|
5170
3568
|
}
|
|
5171
3569
|
if (requirements.binance.backfill) {
|
|
5172
|
-
await
|
|
3570
|
+
await timeOperation2("binance market context backfill", () => {
|
|
5173
3571
|
const backfill = params.mode === "backtest" ? backfillBinanceMarketContextForBacktest : params.mode === "signals" ? backfillBinanceMarketContextForSignals : backfillBinanceMarketContextForReplay;
|
|
5174
3572
|
return backfill(buildBinanceMarketBackfillParams(params));
|
|
5175
3573
|
});
|
|
5176
3574
|
}
|
|
5177
3575
|
if (requirements.coinmarketcap.backfill) {
|
|
5178
|
-
await
|
|
3576
|
+
await timeOperation2(
|
|
5179
3577
|
"coinmarketcap historical context backfill",
|
|
5180
3578
|
() => resolveCoinMarketCapBackfillForMode(params.mode)(
|
|
5181
3579
|
buildCoinMarketCapBackfillParams(params)
|
|
@@ -5197,7 +3595,7 @@ var loadBtcReferenceConnectors = async ({
|
|
|
5197
3595
|
connectorName,
|
|
5198
3596
|
marketConnector,
|
|
5199
3597
|
userName,
|
|
5200
|
-
projectRoot
|
|
3598
|
+
projectRoot,
|
|
5201
3599
|
shouldUseDedicatedReferences,
|
|
5202
3600
|
requireDedicatedReferences = false,
|
|
5203
3601
|
warn
|
|
@@ -5209,8 +3607,8 @@ var loadBtcReferenceConnectors = async ({
|
|
|
5209
3607
|
};
|
|
5210
3608
|
}
|
|
5211
3609
|
const [binanceFactory, coinbaseFactory] = await Promise.all([
|
|
5212
|
-
(0, import_connectors4.getConnectorCreatorByName)(import_connectors3.ConnectorNames.Binance,
|
|
5213
|
-
(0, import_connectors4.getConnectorCreatorByName)(import_connectors3.ConnectorNames.Coinbase,
|
|
3610
|
+
(0, import_connectors4.getConnectorCreatorByName)(import_connectors3.ConnectorNames.Binance, projectRoot),
|
|
3611
|
+
(0, import_connectors4.getConnectorCreatorByName)(import_connectors3.ConnectorNames.Coinbase, projectRoot)
|
|
5214
3612
|
]);
|
|
5215
3613
|
const binance = binanceFactory ? await binanceFactory({ userName }) : marketConnector;
|
|
5216
3614
|
if (!binanceFactory) {
|
|
@@ -5232,7 +3630,7 @@ var updateMarketHistoryWithBtcReferences = async ({
|
|
|
5232
3630
|
marketConnector,
|
|
5233
3631
|
connectorName,
|
|
5234
3632
|
btcReferences,
|
|
5235
|
-
interval
|
|
3633
|
+
interval,
|
|
5236
3634
|
symbols,
|
|
5237
3635
|
preloadDays,
|
|
5238
3636
|
preloadStart,
|
|
@@ -5243,7 +3641,7 @@ var updateMarketHistoryWithBtcReferences = async ({
|
|
|
5243
3641
|
await updatePrimaryMarketHistory({
|
|
5244
3642
|
marketConnector,
|
|
5245
3643
|
connectorName,
|
|
5246
|
-
interval
|
|
3644
|
+
interval,
|
|
5247
3645
|
symbols,
|
|
5248
3646
|
preloadDays,
|
|
5249
3647
|
preloadStart,
|
|
@@ -5254,7 +3652,7 @@ var updateMarketHistoryWithBtcReferences = async ({
|
|
|
5254
3652
|
await updateBtcReferenceHistory({
|
|
5255
3653
|
marketConnector,
|
|
5256
3654
|
btcReferences,
|
|
5257
|
-
interval
|
|
3655
|
+
interval,
|
|
5258
3656
|
preloadDays,
|
|
5259
3657
|
preloadStart,
|
|
5260
3658
|
preloadEnd,
|
|
@@ -5265,7 +3663,7 @@ var updateMarketHistoryWithBtcReferences = async ({
|
|
|
5265
3663
|
var updatePrimaryMarketHistory = async ({
|
|
5266
3664
|
marketConnector,
|
|
5267
3665
|
connectorName,
|
|
5268
|
-
interval
|
|
3666
|
+
interval,
|
|
5269
3667
|
symbols,
|
|
5270
3668
|
preloadDays,
|
|
5271
3669
|
preloadStart,
|
|
@@ -5274,7 +3672,7 @@ var updatePrimaryMarketHistory = async ({
|
|
|
5274
3672
|
universe = marketConnector.universe ?? "crypto"
|
|
5275
3673
|
}) => {
|
|
5276
3674
|
if (!symbols.length) return;
|
|
5277
|
-
const
|
|
3675
|
+
const timeOperation2 = (label, operation) => timeOperation(
|
|
5278
3676
|
label,
|
|
5279
3677
|
operation,
|
|
5280
3678
|
log ?? ((message) => console.log(import_chalk5.default.gray(message)))
|
|
@@ -5284,11 +3682,11 @@ var updatePrimaryMarketHistory = async ({
|
|
|
5284
3682
|
...preloadStart != null ? { preloadStart } : {},
|
|
5285
3683
|
...preloadEnd != null ? { preloadEnd } : {}
|
|
5286
3684
|
} : { connectorLabel: connectorName };
|
|
5287
|
-
await
|
|
3685
|
+
await timeOperation2(
|
|
5288
3686
|
`update ${connectorName}`,
|
|
5289
3687
|
() => (0, import_cli.update)(
|
|
5290
3688
|
marketConnector,
|
|
5291
|
-
|
|
3689
|
+
interval,
|
|
5292
3690
|
universe === "crypto" ? withPrimaryMarketReferenceSymbols(symbols) : symbols,
|
|
5293
3691
|
preloadDays,
|
|
5294
3692
|
updateOptions
|
|
@@ -5298,7 +3696,7 @@ var updatePrimaryMarketHistory = async ({
|
|
|
5298
3696
|
var updateBtcReferenceHistory = async ({
|
|
5299
3697
|
marketConnector,
|
|
5300
3698
|
btcReferences,
|
|
5301
|
-
interval
|
|
3699
|
+
interval,
|
|
5302
3700
|
preloadDays,
|
|
5303
3701
|
preloadStart,
|
|
5304
3702
|
preloadEnd,
|
|
@@ -5306,7 +3704,7 @@ var updateBtcReferenceHistory = async ({
|
|
|
5306
3704
|
universe = marketConnector.universe ?? "crypto"
|
|
5307
3705
|
}) => {
|
|
5308
3706
|
if (universe !== "crypto") return;
|
|
5309
|
-
const
|
|
3707
|
+
const timeOperation2 = (label, operation) => timeOperation(
|
|
5310
3708
|
label,
|
|
5311
3709
|
operation,
|
|
5312
3710
|
log ?? ((message) => console.log(import_chalk5.default.gray(message)))
|
|
@@ -5323,9 +3721,9 @@ var updateBtcReferenceHistory = async ({
|
|
|
5323
3721
|
...preloadStart != null ? { preloadStart } : {},
|
|
5324
3722
|
...preloadEnd != null ? { preloadEnd } : {}
|
|
5325
3723
|
} : { connectorLabel };
|
|
5326
|
-
await
|
|
3724
|
+
await timeOperation2(
|
|
5327
3725
|
`update ${connectorLabel}`,
|
|
5328
|
-
() => (0, import_cli.update)(connector,
|
|
3726
|
+
() => (0, import_cli.update)(connector, interval, ["BTCUSDT"], preloadDays, referenceOptions)
|
|
5329
3727
|
);
|
|
5330
3728
|
};
|
|
5331
3729
|
await updateReference({
|
|
@@ -5341,79 +3739,33 @@ var updateBtcReferenceHistory = async ({
|
|
|
5341
3739
|
// src/lib/signals/runtimeStrategies.ts
|
|
5342
3740
|
var import_logger = require("@tradejs/infra/logger");
|
|
5343
3741
|
var import_redis2 = require("@tradejs/infra/redis");
|
|
5344
|
-
var import_tradingAccounts = require("@tradejs/infra/tradingAccounts");
|
|
5345
|
-
var import_strategies3 = require("@tradejs/node/strategies");
|
|
5346
|
-
|
|
5347
|
-
// src/lib/runtimeRedis.ts
|
|
5348
|
-
var import_redis = require("@tradejs/infra/redis");
|
|
5349
|
-
var import_time = require("@tradejs/core/time");
|
|
5350
|
-
var
|
|
5351
|
-
var
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
if (parts.length !== 5) return null;
|
|
5355
|
-
const [users, keyUserName, strategiesKey, strategyName, configId] = parts;
|
|
5356
|
-
if (users !== "users" || keyUserName !== userName || strategiesKey !== "strategies" || !strategyName || !configId || RESERVED_STRATEGY_NAMES.has(strategyName) || RESERVED_CONFIG_IDS.has(configId) || !/^[a-zA-Z0-9_-]+$/.test(configId)) {
|
|
5357
|
-
return null;
|
|
5358
|
-
}
|
|
5359
|
-
return { strategyName, configId };
|
|
5360
|
-
};
|
|
5361
|
-
var isRuntimeStrategyEnabled = (strategyConfig) => {
|
|
5362
|
-
const enabled = strategyConfig.ENABLE;
|
|
5363
|
-
return enabled !== false;
|
|
5364
|
-
};
|
|
5365
|
-
var resolveStrategyNameByConfigKey = (userName, key) => {
|
|
5366
|
-
return resolveStrategyConfigIdentityByKey(userName, key)?.strategyName ?? null;
|
|
5367
|
-
};
|
|
5368
|
-
var getRuntimeStrategyConfigKeys = async (userName) => {
|
|
5369
|
-
const keys = await (0, import_redis.getKeys)(`${import_redis.redisKeys.strategies(userName)}:`);
|
|
5370
|
-
return keys.filter((key) => resolveStrategyConfigIdentityByKey(userName, key)).sort((left, right) => left.localeCompare(right));
|
|
5371
|
-
};
|
|
5372
|
-
var loadRuntimeStrategyConfigs = async (userName, {
|
|
5373
|
-
onInvalidConfig
|
|
5374
|
-
} = {}) => {
|
|
5375
|
-
const configKeys = await getRuntimeStrategyConfigKeys(userName);
|
|
5376
|
-
const strategyConfigs = await Promise.all(
|
|
5377
|
-
configKeys.map(async (key) => {
|
|
5378
|
-
const strategyName = resolveStrategyNameByConfigKey(userName, key);
|
|
5379
|
-
const identity = resolveStrategyConfigIdentityByKey(userName, key);
|
|
5380
|
-
if (!strategyName || !identity) {
|
|
5381
|
-
return null;
|
|
5382
|
-
}
|
|
5383
|
-
const strategyConfig = await (0, import_redis.getData)(
|
|
5384
|
-
key,
|
|
5385
|
-
null
|
|
5386
|
-
);
|
|
5387
|
-
if (!strategyConfig || typeof strategyConfig !== "object" || Array.isArray(strategyConfig)) {
|
|
5388
|
-
onInvalidConfig?.(key);
|
|
5389
|
-
return null;
|
|
5390
|
-
}
|
|
5391
|
-
return {
|
|
5392
|
-
key,
|
|
5393
|
-
strategyName,
|
|
5394
|
-
configId: identity.configId,
|
|
5395
|
-
strategyConfig
|
|
5396
|
-
};
|
|
5397
|
-
})
|
|
5398
|
-
);
|
|
5399
|
-
return strategyConfigs.filter(Boolean);
|
|
3742
|
+
var import_tradingAccounts = require("@tradejs/infra/tradingAccounts");
|
|
3743
|
+
var import_strategies3 = require("@tradejs/node/strategies");
|
|
3744
|
+
|
|
3745
|
+
// src/lib/runtimeRedis.ts
|
|
3746
|
+
var import_redis = require("@tradejs/infra/redis");
|
|
3747
|
+
var import_time = require("@tradejs/core/time");
|
|
3748
|
+
var import_runtimeStrategyConfigs = require("@tradejs/infra/runtimeStrategyConfigs");
|
|
3749
|
+
var isRuntimeStrategyEnabled = (strategyConfig) => {
|
|
3750
|
+
const enabled = strategyConfig.ENABLE;
|
|
3751
|
+
return enabled !== false;
|
|
5400
3752
|
};
|
|
5401
3753
|
|
|
5402
3754
|
// src/lib/signals/runtimeStrategies.ts
|
|
5403
3755
|
var loadRuntimeStrategies = async ({
|
|
5404
3756
|
userName,
|
|
5405
|
-
projectRoot
|
|
3757
|
+
projectRoot,
|
|
5406
3758
|
deployment,
|
|
5407
3759
|
connectorName = "bybit",
|
|
5408
3760
|
universe,
|
|
5409
3761
|
accountId,
|
|
5410
|
-
interval
|
|
3762
|
+
interval
|
|
5411
3763
|
}) => {
|
|
5412
3764
|
const deploymentStrategies = new Map(
|
|
5413
3765
|
(deployment?.strategies ?? []).filter(({ enabled }) => enabled !== false).map((strategy) => [strategy.strategyName, strategy])
|
|
5414
3766
|
);
|
|
5415
3767
|
const strategyConfigs = await Promise.all(
|
|
5416
|
-
(await loadRuntimeStrategyConfigs(userName)).map(
|
|
3768
|
+
(await (0, import_runtimeStrategyConfigs.loadRuntimeStrategyConfigs)(userName)).map(
|
|
5417
3769
|
async ({
|
|
5418
3770
|
key,
|
|
5419
3771
|
strategyName,
|
|
@@ -5442,7 +3794,7 @@ var loadRuntimeStrategies = async ({
|
|
|
5442
3794
|
});
|
|
5443
3795
|
const effectiveAccountId = resolvedAccount?.id ?? requestedAccountId;
|
|
5444
3796
|
const [strategyCreator, strategyResults] = await Promise.all([
|
|
5445
|
-
(0, import_strategies3.getStrategyCreator)(strategyName,
|
|
3797
|
+
(0, import_strategies3.getStrategyCreator)(strategyName, projectRoot),
|
|
5446
3798
|
(0, import_redis2.getData)(import_redis2.redisKeys.strategyResults(userName, strategyName), {})
|
|
5447
3799
|
]);
|
|
5448
3800
|
if (!strategyCreator) {
|
|
@@ -5483,7 +3835,7 @@ var loadRuntimeStrategies = async ({
|
|
|
5483
3835
|
byStrategyAndAccount.set(conflictKey, candidate);
|
|
5484
3836
|
}
|
|
5485
3837
|
return active.filter(
|
|
5486
|
-
(candidate) => (!universe || candidate.universe === universe) && (!
|
|
3838
|
+
(candidate) => (!universe || candidate.universe === universe) && (!interval || String(candidate.interval) === String(interval)) && (!accountId || candidate.accountId === accountId)
|
|
5487
3839
|
);
|
|
5488
3840
|
};
|
|
5489
3841
|
|
|
@@ -5699,11 +4051,11 @@ var normalizeForStableJson = (value) => {
|
|
|
5699
4051
|
}
|
|
5700
4052
|
return value;
|
|
5701
4053
|
};
|
|
5702
|
-
var resolveRuntimeMaxLossValue = (
|
|
5703
|
-
if (!
|
|
4054
|
+
var resolveRuntimeMaxLossValue = (config2) => {
|
|
4055
|
+
if (!config2 || typeof config2 !== "object" || Array.isArray(config2)) {
|
|
5704
4056
|
return null;
|
|
5705
4057
|
}
|
|
5706
|
-
const strategyConfig =
|
|
4058
|
+
const strategyConfig = config2.strategyConfig;
|
|
5707
4059
|
if (!strategyConfig || typeof strategyConfig !== "object" || Array.isArray(strategyConfig)) {
|
|
5708
4060
|
return null;
|
|
5709
4061
|
}
|
|
@@ -5717,8 +4069,8 @@ var gitLineageCache = /* @__PURE__ */ new Map();
|
|
|
5717
4069
|
var gateFingerprintCache = /* @__PURE__ */ new Map();
|
|
5718
4070
|
var binanceBreadthFingerprintCache = /* @__PURE__ */ new Map();
|
|
5719
4071
|
var snapshotFingerprintCache = /* @__PURE__ */ new Map();
|
|
5720
|
-
var resolveGitLineage = (
|
|
5721
|
-
const cached = gitLineageCache.get(
|
|
4072
|
+
var resolveGitLineage = (projectRoot) => {
|
|
4073
|
+
const cached = gitLineageCache.get(projectRoot);
|
|
5722
4074
|
if (cached) {
|
|
5723
4075
|
return cached;
|
|
5724
4076
|
}
|
|
@@ -5728,12 +4080,12 @@ var resolveGitLineage = (projectRoot2) => {
|
|
|
5728
4080
|
gitSha: envSha,
|
|
5729
4081
|
gitDirty: false
|
|
5730
4082
|
};
|
|
5731
|
-
gitLineageCache.set(
|
|
4083
|
+
gitLineageCache.set(projectRoot, result);
|
|
5732
4084
|
return result;
|
|
5733
4085
|
}
|
|
5734
4086
|
try {
|
|
5735
4087
|
const gitSha = (0, import_node_child_process.execFileSync)("git", ["rev-parse", "HEAD"], {
|
|
5736
|
-
cwd:
|
|
4088
|
+
cwd: projectRoot,
|
|
5737
4089
|
encoding: "utf8",
|
|
5738
4090
|
stdio: ["ignore", "pipe", "ignore"]
|
|
5739
4091
|
}).trim();
|
|
@@ -5741,7 +4093,7 @@ var resolveGitLineage = (projectRoot2) => {
|
|
|
5741
4093
|
"git",
|
|
5742
4094
|
["status", "--porcelain", "--untracked-files=normal"],
|
|
5743
4095
|
{
|
|
5744
|
-
cwd:
|
|
4096
|
+
cwd: projectRoot,
|
|
5745
4097
|
encoding: "utf8",
|
|
5746
4098
|
stdio: ["ignore", "pipe", "ignore"]
|
|
5747
4099
|
}
|
|
@@ -5750,14 +4102,14 @@ var resolveGitLineage = (projectRoot2) => {
|
|
|
5750
4102
|
gitSha: gitSha || null,
|
|
5751
4103
|
gitDirty: status.length > 0
|
|
5752
4104
|
};
|
|
5753
|
-
gitLineageCache.set(
|
|
4105
|
+
gitLineageCache.set(projectRoot, result);
|
|
5754
4106
|
return result;
|
|
5755
4107
|
} catch {
|
|
5756
4108
|
const result = {
|
|
5757
4109
|
gitSha: null,
|
|
5758
4110
|
gitDirty: null
|
|
5759
4111
|
};
|
|
5760
|
-
gitLineageCache.set(
|
|
4112
|
+
gitLineageCache.set(projectRoot, result);
|
|
5761
4113
|
return result;
|
|
5762
4114
|
}
|
|
5763
4115
|
};
|
|
@@ -5768,13 +4120,13 @@ var readOptionalFile = async (filePath) => {
|
|
|
5768
4120
|
return null;
|
|
5769
4121
|
}
|
|
5770
4122
|
};
|
|
5771
|
-
var resolveBinanceBreadthFingerprint = async (
|
|
5772
|
-
if (binanceBreadthFingerprintCache.has(
|
|
5773
|
-
return binanceBreadthFingerprintCache.get(
|
|
4123
|
+
var resolveBinanceBreadthFingerprint = async (projectRoot) => {
|
|
4124
|
+
if (binanceBreadthFingerprintCache.has(projectRoot)) {
|
|
4125
|
+
return binanceBreadthFingerprintCache.get(projectRoot) ?? null;
|
|
5774
4126
|
}
|
|
5775
4127
|
const content = await readOptionalFile(
|
|
5776
4128
|
import_node_path.default.join(
|
|
5777
|
-
|
|
4129
|
+
projectRoot,
|
|
5778
4130
|
"packages/node/src/config/binanceBreadthUniverses.json"
|
|
5779
4131
|
)
|
|
5780
4132
|
);
|
|
@@ -5787,15 +4139,15 @@ var resolveBinanceBreadthFingerprint = async (projectRoot2) => {
|
|
|
5787
4139
|
result = null;
|
|
5788
4140
|
}
|
|
5789
4141
|
}
|
|
5790
|
-
binanceBreadthFingerprintCache.set(
|
|
4142
|
+
binanceBreadthFingerprintCache.set(projectRoot, result);
|
|
5791
4143
|
return result;
|
|
5792
4144
|
};
|
|
5793
|
-
var resolveSnapshotFingerprint = async (
|
|
5794
|
-
const cacheKey = `${
|
|
4145
|
+
var resolveSnapshotFingerprint = async (projectRoot, relativePath) => {
|
|
4146
|
+
const cacheKey = `${projectRoot}:${relativePath}`;
|
|
5795
4147
|
if (snapshotFingerprintCache.has(cacheKey)) {
|
|
5796
4148
|
return snapshotFingerprintCache.get(cacheKey) ?? null;
|
|
5797
4149
|
}
|
|
5798
|
-
const content = await readOptionalFile(import_node_path.default.join(
|
|
4150
|
+
const content = await readOptionalFile(import_node_path.default.join(projectRoot, relativePath));
|
|
5799
4151
|
let result = null;
|
|
5800
4152
|
if (content) {
|
|
5801
4153
|
try {
|
|
@@ -5809,11 +4161,11 @@ var resolveSnapshotFingerprint = async (projectRoot2, relativePath) => {
|
|
|
5809
4161
|
return result;
|
|
5810
4162
|
};
|
|
5811
4163
|
var resolveGateFingerprint = async ({
|
|
5812
|
-
projectRoot
|
|
4164
|
+
projectRoot,
|
|
5813
4165
|
strategyName,
|
|
5814
4166
|
gitSha
|
|
5815
4167
|
}) => {
|
|
5816
|
-
const cacheKey = `${
|
|
4168
|
+
const cacheKey = `${projectRoot}:${strategyName}:${gitSha ?? "unknown"}`;
|
|
5817
4169
|
const cached = gateFingerprintCache.get(cacheKey);
|
|
5818
4170
|
if (cached) {
|
|
5819
4171
|
return cached;
|
|
@@ -5829,7 +4181,7 @@ var resolveGateFingerprint = async ({
|
|
|
5829
4181
|
const optionalEntries = await Promise.all(
|
|
5830
4182
|
relativeCandidates.map(async (relativePath) => {
|
|
5831
4183
|
const content = await readOptionalFile(
|
|
5832
|
-
import_node_path.default.join(
|
|
4184
|
+
import_node_path.default.join(projectRoot, relativePath)
|
|
5833
4185
|
);
|
|
5834
4186
|
return content == null ? null : { relativePath, content };
|
|
5835
4187
|
})
|
|
@@ -5855,19 +4207,19 @@ var resolveGateFingerprint = async ({
|
|
|
5855
4207
|
return fingerprint;
|
|
5856
4208
|
};
|
|
5857
4209
|
var buildRuntimeLineage = async ({
|
|
5858
|
-
projectRoot
|
|
4210
|
+
projectRoot,
|
|
5859
4211
|
strategyName,
|
|
5860
|
-
config,
|
|
4212
|
+
config: config2,
|
|
5861
4213
|
runContext,
|
|
5862
4214
|
env = process.env
|
|
5863
4215
|
}) => {
|
|
5864
|
-
const git = resolveGitLineage(
|
|
4216
|
+
const git = resolveGitLineage(projectRoot);
|
|
5865
4217
|
const hyperliquidPerpUniverseFingerprint = typeof import_strategies4.getHyperliquidPerpUniverseSnapshot === "function" ? (0, import_strategies4.getHyperliquidPerpUniverseSnapshot)().fingerprint : await resolveSnapshotFingerprint(
|
|
5866
|
-
|
|
4218
|
+
projectRoot,
|
|
5867
4219
|
"packages/node/src/config/hyperliquidPerpUniverse.json"
|
|
5868
4220
|
);
|
|
5869
4221
|
const hyperliquidWhaleRegistryFingerprint = typeof import_strategies4.getHyperliquidWhaleRegistrySnapshot === "function" ? (0, import_strategies4.getHyperliquidWhaleRegistrySnapshot)().fingerprint : await resolveSnapshotFingerprint(
|
|
5870
|
-
|
|
4222
|
+
projectRoot,
|
|
5871
4223
|
"packages/node/src/config/hyperliquidWhales.json"
|
|
5872
4224
|
);
|
|
5873
4225
|
const context = {
|
|
@@ -5875,7 +4227,7 @@ var buildRuntimeLineage = async ({
|
|
|
5875
4227
|
RUNTIME_CONTEXT_ENV_KEYS.map((key) => [key, env[key] ?? null])
|
|
5876
4228
|
),
|
|
5877
4229
|
...RUNTIME_CONTEXT_DATA_MODEL,
|
|
5878
|
-
binanceBreadthUniverseFingerprint: await resolveBinanceBreadthFingerprint(
|
|
4230
|
+
binanceBreadthUniverseFingerprint: await resolveBinanceBreadthFingerprint(projectRoot),
|
|
5879
4231
|
hyperliquidPerpUniverseFingerprint,
|
|
5880
4232
|
hyperliquidWhaleRegistryFingerprint,
|
|
5881
4233
|
...runContext
|
|
@@ -5884,13 +4236,13 @@ var buildRuntimeLineage = async ({
|
|
|
5884
4236
|
schemaVersion: 1,
|
|
5885
4237
|
...git,
|
|
5886
4238
|
gateFingerprint: await resolveGateFingerprint({
|
|
5887
|
-
projectRoot
|
|
4239
|
+
projectRoot,
|
|
5888
4240
|
strategyName,
|
|
5889
4241
|
gitSha: git.gitSha
|
|
5890
4242
|
}),
|
|
5891
|
-
configFingerprint: fingerprintRuntimeValue(
|
|
4243
|
+
configFingerprint: fingerprintRuntimeValue(config2),
|
|
5892
4244
|
contextFingerprint: fingerprintRuntimeValue(context),
|
|
5893
|
-
maxLossValue: resolveRuntimeMaxLossValue(
|
|
4245
|
+
maxLossValue: resolveRuntimeMaxLossValue(config2)
|
|
5894
4246
|
};
|
|
5895
4247
|
};
|
|
5896
4248
|
var runtimeLineageKey = (lineage) => [
|
|
@@ -6080,23 +4432,6 @@ var getTelegramDeliverableSignals = (signals2) => signals2.filter(
|
|
|
6080
4432
|
(signal) => signal.orderStatus !== "skipped" && signal.orderStatus !== "canceled"
|
|
6081
4433
|
);
|
|
6082
4434
|
|
|
6083
|
-
// src/lib/runtimeModeConfig.ts
|
|
6084
|
-
var buildRuntimeModeStrategyConfig = ({
|
|
6085
|
-
strategyConfig,
|
|
6086
|
-
env,
|
|
6087
|
-
interval: interval2,
|
|
6088
|
-
makeOrders,
|
|
6089
|
-
recordRuntimeTrades,
|
|
6090
|
-
aiReplayAnalyses
|
|
6091
|
-
}) => ({
|
|
6092
|
-
...strategyConfig,
|
|
6093
|
-
ENV: env,
|
|
6094
|
-
MAKE_ORDERS: makeOrders,
|
|
6095
|
-
INTERVAL: interval2,
|
|
6096
|
-
...typeof recordRuntimeTrades === "boolean" ? { RECORD_RUNTIME_TRADES: recordRuntimeTrades } : {},
|
|
6097
|
-
...aiReplayAnalyses?.length ? { AI_REPLAY_ANALYSES: aiReplayAnalyses } : {}
|
|
6098
|
-
});
|
|
6099
|
-
|
|
6100
4435
|
// src/lib/signals/runtimeLifecycle.ts
|
|
6101
4436
|
var stableStringify = (value) => {
|
|
6102
4437
|
if (value == null || typeof value !== "object") {
|
|
@@ -6114,13 +4449,13 @@ var buildSignalsStrategyLifecycleKey = ({
|
|
|
6114
4449
|
accountId,
|
|
6115
4450
|
deploymentId,
|
|
6116
4451
|
symbol,
|
|
6117
|
-
interval
|
|
4452
|
+
interval,
|
|
6118
4453
|
strategyName,
|
|
6119
4454
|
configId
|
|
6120
4455
|
}) => {
|
|
6121
4456
|
const namedConfigId = configId && configId !== "config" ? configId : void 0;
|
|
6122
4457
|
if (!universe && !accountId && !deploymentId) {
|
|
6123
|
-
return [connectorName, symbol,
|
|
4458
|
+
return [connectorName, symbol, interval, strategyName, namedConfigId].filter(Boolean).join(":");
|
|
6124
4459
|
}
|
|
6125
4460
|
return [
|
|
6126
4461
|
connectorName,
|
|
@@ -6128,17 +4463,17 @@ var buildSignalsStrategyLifecycleKey = ({
|
|
|
6128
4463
|
accountId ?? "default",
|
|
6129
4464
|
deploymentId ?? "default",
|
|
6130
4465
|
symbol,
|
|
6131
|
-
|
|
4466
|
+
interval,
|
|
6132
4467
|
strategyName,
|
|
6133
4468
|
namedConfigId
|
|
6134
4469
|
].filter(Boolean).join(":");
|
|
6135
4470
|
};
|
|
6136
4471
|
var createSignalsStrategyLifecycle = ({
|
|
6137
|
-
intervalMs
|
|
4472
|
+
intervalMs,
|
|
6138
4473
|
maxLiveBars,
|
|
6139
4474
|
releaseState = () => void 0
|
|
6140
4475
|
}) => {
|
|
6141
|
-
if (!Number.isFinite(
|
|
4476
|
+
if (!Number.isFinite(intervalMs) || intervalMs <= 0) {
|
|
6142
4477
|
throw new Error("Signals strategy lifecycle requires a positive interval");
|
|
6143
4478
|
}
|
|
6144
4479
|
if (!Number.isFinite(maxLiveBars) || maxLiveBars <= 0) {
|
|
@@ -6149,7 +4484,7 @@ var createSignalsStrategyLifecycle = ({
|
|
|
6149
4484
|
const evaluate = async ({
|
|
6150
4485
|
key,
|
|
6151
4486
|
timestamp,
|
|
6152
|
-
config,
|
|
4487
|
+
config: config2,
|
|
6153
4488
|
btcBinanceData,
|
|
6154
4489
|
btcCoinbaseData,
|
|
6155
4490
|
onRuntimeClose,
|
|
@@ -6159,7 +4494,7 @@ var createSignalsStrategyLifecycle = ({
|
|
|
6159
4494
|
if (!Number.isFinite(timestamp)) {
|
|
6160
4495
|
throw new Error(`Signals strategy lifecycle received ${timestamp}`);
|
|
6161
4496
|
}
|
|
6162
|
-
const configFingerprint = stableStringify(
|
|
4497
|
+
const configFingerprint = stableStringify(config2);
|
|
6163
4498
|
const current = entries.get(key);
|
|
6164
4499
|
if (current) {
|
|
6165
4500
|
if (timestamp === current.lastTimestamp) {
|
|
@@ -6172,7 +4507,7 @@ var createSignalsStrategyLifecycle = ({
|
|
|
6172
4507
|
let action = "created";
|
|
6173
4508
|
if (current && current.configFingerprint !== configFingerprint) {
|
|
6174
4509
|
action = "rebuilt_config";
|
|
6175
|
-
} else if (current && timestamp !== current.lastTimestamp +
|
|
4510
|
+
} else if (current && timestamp !== current.lastTimestamp + intervalMs) {
|
|
6176
4511
|
action = "rebuilt_gap";
|
|
6177
4512
|
} else if (current && current.processedBars >= normalizedMaxLiveBars) {
|
|
6178
4513
|
action = "rebuilt_limit";
|
|
@@ -6228,18 +4563,18 @@ var createSignalsStrategyLifecycle = ({
|
|
|
6228
4563
|
// src/lib/signals/daemon.ts
|
|
6229
4564
|
var getNextSignalsCycleDelay = ({
|
|
6230
4565
|
now,
|
|
6231
|
-
intervalMs
|
|
4566
|
+
intervalMs,
|
|
6232
4567
|
settleDelayMs
|
|
6233
4568
|
}) => {
|
|
6234
|
-
const nextBoundary = (Math.floor(now /
|
|
4569
|
+
const nextBoundary = (Math.floor(now / intervalMs) + 1) * intervalMs;
|
|
6235
4570
|
return Math.max(0, nextBoundary + settleDelayMs - now);
|
|
6236
4571
|
};
|
|
6237
4572
|
var getCurrentSignalsCycleDelay = ({
|
|
6238
4573
|
now,
|
|
6239
|
-
intervalMs
|
|
4574
|
+
intervalMs,
|
|
6240
4575
|
settleDelayMs
|
|
6241
4576
|
}) => {
|
|
6242
|
-
const currentBoundary = Math.floor(now /
|
|
4577
|
+
const currentBoundary = Math.floor(now / intervalMs) * intervalMs;
|
|
6243
4578
|
return Math.max(0, currentBoundary + settleDelayMs - now);
|
|
6244
4579
|
};
|
|
6245
4580
|
var getSignalsHeartbeatStatus = ({
|
|
@@ -6266,7 +4601,7 @@ var waitForNextCycle = (delayMs, signal) => new Promise((resolve) => {
|
|
|
6266
4601
|
});
|
|
6267
4602
|
var runSignalsDaemon = async ({
|
|
6268
4603
|
runCycle,
|
|
6269
|
-
intervalMs
|
|
4604
|
+
intervalMs,
|
|
6270
4605
|
settleDelayMs,
|
|
6271
4606
|
signal,
|
|
6272
4607
|
onCycleError,
|
|
@@ -6275,7 +4610,7 @@ var runSignalsDaemon = async ({
|
|
|
6275
4610
|
}) => {
|
|
6276
4611
|
const initialDelay = getCurrentSignalsCycleDelay({
|
|
6277
4612
|
now: now(),
|
|
6278
|
-
intervalMs
|
|
4613
|
+
intervalMs,
|
|
6279
4614
|
settleDelayMs
|
|
6280
4615
|
});
|
|
6281
4616
|
if (initialDelay > 0) {
|
|
@@ -6285,7 +4620,7 @@ var runSignalsDaemon = async ({
|
|
|
6285
4620
|
const cycleStartedAt = now();
|
|
6286
4621
|
const nextCycleAt = cycleStartedAt + getNextSignalsCycleDelay({
|
|
6287
4622
|
now: cycleStartedAt,
|
|
6288
|
-
intervalMs
|
|
4623
|
+
intervalMs,
|
|
6289
4624
|
settleDelayMs
|
|
6290
4625
|
});
|
|
6291
4626
|
try {
|
|
@@ -6303,7 +4638,7 @@ var runSignalsDaemon = async ({
|
|
|
6303
4638
|
// src/lib/signals/klineFeed.ts
|
|
6304
4639
|
var import_connectors5 = require("@tradejs/connectors");
|
|
6305
4640
|
var import_logger3 = require("@tradejs/infra/logger");
|
|
6306
|
-
var
|
|
4641
|
+
var import_candles = require("@tradejs/infra/timescale/candles");
|
|
6307
4642
|
|
|
6308
4643
|
// src/lib/marketData/klineEvents.ts
|
|
6309
4644
|
var import_ioredis = __toESM(require("ioredis"));
|
|
@@ -6317,15 +4652,15 @@ var normalizeSymbols2 = (symbols) => [...new Set(symbols.map((symbol) => symbol.
|
|
|
6317
4652
|
Boolean
|
|
6318
4653
|
);
|
|
6319
4654
|
var createSignalsKlineFeed = async ({
|
|
6320
|
-
config,
|
|
6321
|
-
interval
|
|
4655
|
+
config: config2,
|
|
4656
|
+
interval,
|
|
6322
4657
|
universe,
|
|
6323
4658
|
publish = publishMarketKlineEvent,
|
|
6324
4659
|
persist = async (rows) => {
|
|
6325
|
-
const intervalMinutes = Number(
|
|
6326
|
-
await (0,
|
|
4660
|
+
const intervalMinutes = Number(interval);
|
|
4661
|
+
await (0, import_candles.upsertCandles)(
|
|
6327
4662
|
rows.flatMap(
|
|
6328
|
-
({ symbol, candle }) => (0,
|
|
4663
|
+
({ symbol, candle }) => (0, import_candles.toRows)("bybit", symbol, intervalMinutes, [candle])
|
|
6329
4664
|
)
|
|
6330
4665
|
);
|
|
6331
4666
|
},
|
|
@@ -6368,14 +4703,14 @@ var createSignalsKlineFeed = async ({
|
|
|
6368
4703
|
}, FLUSH_DELAY_MS);
|
|
6369
4704
|
};
|
|
6370
4705
|
const stream = await streamFactory({
|
|
6371
|
-
config,
|
|
4706
|
+
config: config2,
|
|
6372
4707
|
onEvent: (event) => {
|
|
6373
|
-
if (event.interval !==
|
|
4708
|
+
if (event.interval !== interval) return;
|
|
6374
4709
|
void publish({
|
|
6375
4710
|
provider: "bybit",
|
|
6376
4711
|
universe,
|
|
6377
4712
|
symbol: event.symbol,
|
|
6378
|
-
interval
|
|
4713
|
+
interval,
|
|
6379
4714
|
candle: event.candle,
|
|
6380
4715
|
confirm: event.confirm,
|
|
6381
4716
|
receivedAt: event.receivedAt
|
|
@@ -6394,7 +4729,7 @@ var createSignalsKlineFeed = async ({
|
|
|
6394
4729
|
});
|
|
6395
4730
|
return {
|
|
6396
4731
|
setSubscriptions: (symbols) => {
|
|
6397
|
-
stream.setSubscriptions(normalizeSymbols2(symbols),
|
|
4732
|
+
stream.setSubscriptions(normalizeSymbols2(symbols), interval);
|
|
6398
4733
|
},
|
|
6399
4734
|
waitForClosed: async ({ symbols, timestamp, timeoutMs, signal }) => {
|
|
6400
4735
|
const expected = normalizeSymbols2(symbols);
|
|
@@ -6432,197 +4767,82 @@ var createSignalsKlineFeed = async ({
|
|
|
6432
4767
|
};
|
|
6433
4768
|
};
|
|
6434
4769
|
|
|
6435
|
-
// src/
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
|
|
6454
|
-
false
|
|
6455
|
-
);
|
|
6456
|
-
import_args.default.option(["c", "chunk"], "Split by chunks, ex. 1/3");
|
|
6457
|
-
import_args.default.option(["U", "user"], "Use user confg", "root");
|
|
6458
|
-
import_args.default.option(["w", "watch"], "Keep signals running on candle boundaries", false);
|
|
6459
|
-
import_args.default.option(
|
|
6460
|
-
["d", "settleDelayMs"],
|
|
6461
|
-
"Delay after candle close before a daemon cycle",
|
|
6462
|
-
Number(process.env.SIGNALS_DAEMON_SETTLE_DELAY_MS || 5e3)
|
|
6463
|
-
);
|
|
6464
|
-
import_args.default.option(
|
|
6465
|
-
["o", "connector"],
|
|
6466
|
-
"Connector provider or name for signals (e.g. bybit, binance, coinbase, custom)",
|
|
6467
|
-
"bybit"
|
|
6468
|
-
);
|
|
6469
|
-
import_args.default.option(["V", "universe"], "Market universe (crypto or tradfi)", "crypto");
|
|
6470
|
-
import_args.default.option(["A", "account"], "Trading account id");
|
|
6471
|
-
import_args.default.option(["D", "deployment"], "Runtime deployment id");
|
|
6472
|
-
var SLOW_SIGNALS_WARNING_MS = 10 * 6e4;
|
|
6473
|
-
var projectRoot = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
|
|
6474
|
-
var flags = import_args.default.parse(process.argv);
|
|
6475
|
-
var interval = flags.timeframe.toString();
|
|
6476
|
-
var intervalMs = Number(interval) * 6e4;
|
|
6477
|
-
var formatDuration2 = (durationMs) => `${(durationMs / 1e3).toFixed(1)}s`;
|
|
6478
|
-
var resolvePositiveInteger = (value, fallback) => {
|
|
6479
|
-
const parsed = Number(value);
|
|
6480
|
-
if (!Number.isFinite(parsed)) {
|
|
6481
|
-
return fallback;
|
|
6482
|
-
}
|
|
6483
|
-
const normalized = Math.floor(parsed);
|
|
6484
|
-
return normalized > 0 ? normalized : fallback;
|
|
6485
|
-
};
|
|
6486
|
-
var resolveNonNegativeInteger = (value, fallback) => {
|
|
6487
|
-
const parsed = Number(value);
|
|
6488
|
-
if (!Number.isFinite(parsed)) {
|
|
6489
|
-
return fallback;
|
|
6490
|
-
}
|
|
6491
|
-
return Math.max(0, Math.floor(parsed));
|
|
6492
|
-
};
|
|
6493
|
-
var resolveSignalsDaemonMaxLiveBars = (runtimeInterval = interval) => {
|
|
6494
|
-
const intervalMinutes = Number(runtimeInterval);
|
|
6495
|
-
const preloadBars = Math.ceil(
|
|
6496
|
-
import_constants3.SIGNALS_CLI_PRELOAD_DAYS * 24 * 60 / intervalMinutes
|
|
6497
|
-
);
|
|
6498
|
-
return resolvePositiveInteger(
|
|
6499
|
-
process.env.SIGNALS_DAEMON_MAX_LIVE_BARS,
|
|
6500
|
-
preloadBars
|
|
6501
|
-
);
|
|
6502
|
-
};
|
|
6503
|
-
var isSignalsKlineWsEnabled = () => !["0", "false", "off", "no"].includes(
|
|
6504
|
-
String(process.env.SIGNALS_KLINE_WS_ENABLED ?? "true").trim().toLowerCase()
|
|
6505
|
-
);
|
|
6506
|
-
var resolveSignalsKlineWsWaitMs = () => resolveNonNegativeInteger(process.env.SIGNALS_KLINE_WS_WAIT_MS, 1e4);
|
|
6507
|
-
var createDefaultSignalsLifecycle = (runtimeInterval = interval) => createSignalsStrategyLifecycle({
|
|
6508
|
-
intervalMs: Number(runtimeInterval) * 6e4,
|
|
6509
|
-
maxLiveBars: resolveSignalsDaemonMaxLiveBars(runtimeInterval),
|
|
6510
|
-
releaseState: import_strategies5.releaseStrategyReplayCache
|
|
4770
|
+
// src/lib/signals/tickerEvaluator.ts
|
|
4771
|
+
var import_strategies5 = require("@tradejs/node/strategies");
|
|
4772
|
+
var import_logger4 = require("@tradejs/infra/logger");
|
|
4773
|
+
|
|
4774
|
+
// src/lib/runtimeModeConfig.ts
|
|
4775
|
+
var buildRuntimeModeStrategyConfig = ({
|
|
4776
|
+
strategyConfig,
|
|
4777
|
+
env,
|
|
4778
|
+
interval,
|
|
4779
|
+
makeOrders,
|
|
4780
|
+
recordRuntimeTrades,
|
|
4781
|
+
aiReplayAnalyses
|
|
4782
|
+
}) => ({
|
|
4783
|
+
...strategyConfig,
|
|
4784
|
+
ENV: env,
|
|
4785
|
+
MAKE_ORDERS: makeOrders,
|
|
4786
|
+
INTERVAL: interval,
|
|
4787
|
+
...typeof recordRuntimeTrades === "boolean" ? { RECORD_RUNTIME_TRADES: recordRuntimeTrades } : {},
|
|
4788
|
+
...aiReplayAnalyses?.length ? { AI_REPLAY_ANALYSES: aiReplayAnalyses } : {}
|
|
6511
4789
|
});
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
`Status: <b>${params.status}</b>`,
|
|
6522
|
-
`Found signals: <b>${params.found}</b>`
|
|
6523
|
-
].join("\n");
|
|
6524
|
-
var resolveSignalsConnectorName = async (value) => {
|
|
6525
|
-
const connectorName = await (0, import_connectors6.resolveConnectorName)(value, projectRoot);
|
|
6526
|
-
if (connectorName) {
|
|
6527
|
-
return connectorName;
|
|
6528
|
-
}
|
|
6529
|
-
import_logger4.logger.warn(
|
|
6530
|
-
'Unknown connector "%s". Fallback to %s.',
|
|
6531
|
-
String(value || "").trim() || String(value),
|
|
6532
|
-
import_connectors6.DEFAULT_CONNECTOR_NAME
|
|
6533
|
-
);
|
|
6534
|
-
return import_connectors6.DEFAULT_CONNECTOR_NAME;
|
|
6535
|
-
};
|
|
6536
|
-
var createSignalsSession = async (lifecycle, scope = {}) => {
|
|
6537
|
-
const deployment = flags.deployment ? await (0, import_tradingAccounts2.getRuntimeDeployment)(flags.user, String(flags.deployment)) : null;
|
|
6538
|
-
if (flags.deployment && !deployment) {
|
|
6539
|
-
throw new Error(`Runtime deployment not found: ${flags.deployment}`);
|
|
6540
|
-
}
|
|
6541
|
-
if (deployment && !deployment.enabled) {
|
|
6542
|
-
throw new Error(`Runtime deployment is disabled: ${deployment.id}`);
|
|
6543
|
-
}
|
|
6544
|
-
const requestedRuntimeInterval = scope.interval ?? interval;
|
|
6545
|
-
const runtimeInterval = deployment?.interval ?? requestedRuntimeInterval;
|
|
6546
|
-
const runtimeIntervalMs = Number(runtimeInterval) * 6e4;
|
|
6547
|
-
if (!Number.isFinite(runtimeIntervalMs) || runtimeIntervalMs <= 0) {
|
|
6548
|
-
throw new Error(`Invalid runtime timeframe: ${runtimeInterval}`);
|
|
6549
|
-
}
|
|
6550
|
-
if (deployment && String(deployment.interval) !== String(requestedRuntimeInterval)) {
|
|
6551
|
-
throw new Error(
|
|
6552
|
-
`Deployment ${deployment.id} requires timeframe ${deployment.interval}; received ${requestedRuntimeInterval}`
|
|
6553
|
-
);
|
|
6554
|
-
}
|
|
6555
|
-
const connectorName = await resolveSignalsConnectorName(
|
|
6556
|
-
deployment?.connectorName ?? scope.connectorName ?? flags.connector
|
|
6557
|
-
);
|
|
6558
|
-
const universe = deployment?.universe ?? scope.universe ?? flags.universe;
|
|
6559
|
-
const requestedAccountId = deployment?.accountId ?? scope.accountId ?? flags.account;
|
|
6560
|
-
const connectorFactory = await (0, import_connectors6.getConnectorCreatorByName)(
|
|
6561
|
-
connectorName,
|
|
6562
|
-
projectRoot
|
|
6563
|
-
);
|
|
6564
|
-
if (!connectorFactory) {
|
|
6565
|
-
throw new Error(`Connector "${connectorName}" is not registered`);
|
|
6566
|
-
}
|
|
6567
|
-
const marketConnector = await connectorFactory({
|
|
6568
|
-
userName: flags.user,
|
|
6569
|
-
universe,
|
|
6570
|
-
accountId: requestedAccountId,
|
|
6571
|
-
deploymentId: deployment?.id
|
|
6572
|
-
});
|
|
6573
|
-
const btcReferences = await loadBtcReferenceConnectors({
|
|
6574
|
-
connectorName,
|
|
6575
|
-
marketConnector,
|
|
6576
|
-
userName: flags.user,
|
|
6577
|
-
projectRoot,
|
|
6578
|
-
shouldUseDedicatedReferences: universe === "crypto" && connectorName.toLowerCase() === import_connectors6.DEFAULT_CONNECTOR_NAME.toLowerCase(),
|
|
6579
|
-
warn: (message) => import_logger4.logger.warn(message)
|
|
6580
|
-
});
|
|
6581
|
-
return {
|
|
4790
|
+
|
|
4791
|
+
// src/lib/signals/tickerEvaluator.ts
|
|
4792
|
+
var createSignalsTickerEvaluator = ({
|
|
4793
|
+
userName,
|
|
4794
|
+
makeOrders,
|
|
4795
|
+
projectRoot,
|
|
4796
|
+
context
|
|
4797
|
+
}) => async (symbol, instrument) => {
|
|
4798
|
+
const {
|
|
6582
4799
|
connectorName,
|
|
4800
|
+
connector,
|
|
4801
|
+
btcBinanceData,
|
|
4802
|
+
btcCoinbaseData,
|
|
4803
|
+
primaryBtcClosedData,
|
|
4804
|
+
primaryEthClosedData,
|
|
4805
|
+
primaryEthByTimestamp,
|
|
4806
|
+
runtimeStrategies,
|
|
4807
|
+
strategyStats,
|
|
4808
|
+
runtimeCloseNotifications,
|
|
4809
|
+
lifecycle,
|
|
4810
|
+
preloadStart,
|
|
4811
|
+
currentTimestamp,
|
|
4812
|
+
persistStrategyState,
|
|
6583
4813
|
universe,
|
|
6584
|
-
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
|
|
6588
|
-
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCoinbaseData, primaryBtcClosedData, primaryEthClosedData, primaryEthByTimestamp, runtimeStrategies, strategyStats, runtimeCloseNotifications, lifecycle, preloadStart, currentTimestamp, persistStrategyState, universe, interval2, intervalMs2, accountId, deploymentId, instrument, runtimeScopeUniverse, saveRuntimeSignalEvaluation, saveRuntimeSignal) => {
|
|
6595
|
-
const strategySignals = [];
|
|
6596
|
-
const loadCached = (cachedSymbol) => connector.kline({
|
|
6597
|
-
symbol: cachedSymbol,
|
|
4814
|
+
interval,
|
|
4815
|
+
intervalMs,
|
|
4816
|
+
accountId,
|
|
4817
|
+
deploymentId,
|
|
4818
|
+
runtimeScopeUniverse,
|
|
4819
|
+
saveRuntimeSignalEvaluation,
|
|
4820
|
+
saveRuntimeSignal
|
|
4821
|
+
} = context;
|
|
4822
|
+
const cachedData = universe === "crypto" && symbol === "BTCUSDT" ? primaryBtcClosedData : universe === "crypto" && symbol === "ETHUSDT" ? primaryEthClosedData : await connector.kline({
|
|
4823
|
+
symbol,
|
|
6598
4824
|
start: preloadStart,
|
|
6599
4825
|
end: currentTimestamp,
|
|
6600
4826
|
cacheOnly: true,
|
|
6601
|
-
interval
|
|
4827
|
+
interval
|
|
6602
4828
|
});
|
|
6603
|
-
const cachedData = universe === "crypto" && symbol === "BTCUSDT" ? primaryBtcClosedData : universe === "crypto" && symbol === "ETHUSDT" ? primaryEthClosedData : await loadCached(symbol);
|
|
6604
4829
|
const closedData = getClosedCandlesForInterval(
|
|
6605
4830
|
cachedData,
|
|
6606
4831
|
currentTimestamp,
|
|
6607
|
-
|
|
6608
|
-
);
|
|
6609
|
-
const closedBtcData = primaryBtcClosedData;
|
|
6610
|
-
const closedEthData = primaryEthClosedData;
|
|
6611
|
-
const { alignedCoinCandles, alignedBtcCandles } = universe === "crypto" ? alignSymbolWithBtcReference(closedData, closedBtcData) : { alignedCoinCandles: closedData, alignedBtcCandles: closedData };
|
|
6612
|
-
const alignedEthCandles = alignedCoinCandles.map((candle) => primaryEthByTimestamp.get(candle.timestamp)).filter(
|
|
6613
|
-
(candle) => Boolean(candle)
|
|
4832
|
+
intervalMs
|
|
6614
4833
|
);
|
|
4834
|
+
const { alignedCoinCandles, alignedBtcCandles } = universe === "crypto" ? alignSymbolWithBtcReference(closedData, primaryBtcClosedData) : { alignedCoinCandles: closedData, alignedBtcCandles: closedData };
|
|
4835
|
+
const alignedEthCandles = alignedCoinCandles.map((candle) => primaryEthByTimestamp.get(candle.timestamp)).filter((candle) => Boolean(candle));
|
|
6615
4836
|
const lastCandle = alignedCoinCandles.at(-1);
|
|
6616
4837
|
const btcLastCandle = alignedBtcCandles.at(-1);
|
|
6617
|
-
const ethLastCandle = lastCandle
|
|
6618
|
-
if (!lastCandle || !btcLastCandle)
|
|
6619
|
-
return strategySignals;
|
|
6620
|
-
}
|
|
4838
|
+
const ethLastCandle = lastCandle ? primaryEthByTimestamp.get(lastCandle.timestamp) : void 0;
|
|
4839
|
+
if (!lastCandle || !btcLastCandle) return [];
|
|
6621
4840
|
const previousData = alignedCoinCandles.slice(0, -1);
|
|
6622
4841
|
const previousBtcData = alignedBtcCandles.slice(0, -1);
|
|
6623
4842
|
const previousEthData = alignedEthCandles.filter(
|
|
6624
4843
|
(candle) => candle.timestamp < lastCandle.timestamp
|
|
6625
4844
|
);
|
|
4845
|
+
const strategySignals = [];
|
|
6626
4846
|
for (const runtimeStrategy of runtimeStrategies) {
|
|
6627
4847
|
const {
|
|
6628
4848
|
strategyName,
|
|
@@ -6632,23 +4852,20 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
6632
4852
|
strategyConfig,
|
|
6633
4853
|
strategyResults
|
|
6634
4854
|
} = runtimeStrategy;
|
|
4855
|
+
const symbolResultConfig = strategyResults?.[symbol]?.config ?? null;
|
|
6635
4856
|
const runtimeConfig = buildRuntimeModeStrategyConfig({
|
|
6636
4857
|
strategyConfig,
|
|
6637
4858
|
env: "CRON",
|
|
6638
|
-
interval
|
|
6639
|
-
makeOrders
|
|
4859
|
+
interval,
|
|
4860
|
+
makeOrders
|
|
6640
4861
|
});
|
|
6641
4862
|
const runtimeLineage = await buildRuntimeLineage({
|
|
6642
4863
|
projectRoot,
|
|
6643
4864
|
strategyName,
|
|
6644
|
-
config: {
|
|
6645
|
-
configId,
|
|
6646
|
-
strategyConfig,
|
|
6647
|
-
symbolResultConfig: strategyResults?.[symbol]?.config ?? null
|
|
6648
|
-
},
|
|
4865
|
+
config: { configId, strategyConfig, symbolResultConfig },
|
|
6649
4866
|
runContext: {
|
|
6650
4867
|
connectorName: connectorName.toLowerCase(),
|
|
6651
|
-
interval: String(
|
|
4868
|
+
interval: String(interval),
|
|
6652
4869
|
universe
|
|
6653
4870
|
}
|
|
6654
4871
|
});
|
|
@@ -6658,40 +4875,36 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
6658
4875
|
accountId,
|
|
6659
4876
|
deploymentId,
|
|
6660
4877
|
symbol,
|
|
6661
|
-
interval
|
|
4878
|
+
interval,
|
|
6662
4879
|
strategyName,
|
|
6663
4880
|
configId
|
|
6664
4881
|
});
|
|
6665
4882
|
const stats = strategyStats.get(strategyName);
|
|
6666
|
-
const
|
|
6667
|
-
|
|
6668
|
-
|
|
4883
|
+
const initialLengths = [
|
|
4884
|
+
previousData.length,
|
|
4885
|
+
previousBtcData.length,
|
|
4886
|
+
previousEthData.length
|
|
4887
|
+
];
|
|
6669
4888
|
let evaluation;
|
|
6670
4889
|
try {
|
|
6671
4890
|
evaluation = await lifecycle.evaluate({
|
|
6672
4891
|
key: lifecycleKey,
|
|
6673
4892
|
timestamp: lastCandle.timestamp,
|
|
6674
|
-
config: {
|
|
6675
|
-
runtimeConfig,
|
|
6676
|
-
sourceStrategyConfig,
|
|
6677
|
-
symbolResultConfig: strategyResults?.[symbol]?.config ?? null
|
|
6678
|
-
},
|
|
4893
|
+
config: { runtimeConfig, sourceStrategyConfig, symbolResultConfig },
|
|
6679
4894
|
btcBinanceData,
|
|
6680
4895
|
btcCoinbaseData,
|
|
6681
|
-
onRuntimeClose: (event) =>
|
|
6682
|
-
|
|
6683
|
-
},
|
|
6684
|
-
create: async ({
|
|
4896
|
+
onRuntimeClose: (event) => runtimeCloseNotifications.push(event),
|
|
4897
|
+
create: ({
|
|
6685
4898
|
btcBinanceData: lifecycleBtcBinanceData,
|
|
6686
4899
|
btcCoinbaseData: lifecycleBtcCoinbaseData,
|
|
6687
4900
|
onRuntimeClose
|
|
6688
4901
|
}) => strategyCreator({
|
|
6689
|
-
userName
|
|
4902
|
+
userName,
|
|
6690
4903
|
connectorName,
|
|
6691
4904
|
runtimeConfigId: configId,
|
|
6692
4905
|
runtimeConfigSnapshot: {
|
|
6693
4906
|
userConfig: sourceStrategyConfig,
|
|
6694
|
-
symbolResultConfig
|
|
4907
|
+
symbolResultConfig
|
|
6695
4908
|
},
|
|
6696
4909
|
connector,
|
|
6697
4910
|
symbol,
|
|
@@ -6714,9 +4927,9 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
6714
4927
|
run: (strategy) => strategy(lastCandle, btcLastCandle, ethLastCandle)
|
|
6715
4928
|
});
|
|
6716
4929
|
} finally {
|
|
6717
|
-
previousData.length =
|
|
6718
|
-
previousBtcData.length =
|
|
6719
|
-
previousEthData.length =
|
|
4930
|
+
previousData.length = initialLengths[0];
|
|
4931
|
+
previousBtcData.length = initialLengths[1];
|
|
4932
|
+
previousEthData.length = initialLengths[2];
|
|
6720
4933
|
}
|
|
6721
4934
|
if (evaluation.action === "duplicate" || evaluation.action === "stale") {
|
|
6722
4935
|
continue;
|
|
@@ -6729,9 +4942,7 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
6729
4942
|
symbol
|
|
6730
4943
|
);
|
|
6731
4944
|
}
|
|
6732
|
-
if (stats)
|
|
6733
|
-
stats.evaluated += 1;
|
|
6734
|
-
}
|
|
4945
|
+
if (stats) stats.evaluated += 1;
|
|
6735
4946
|
const signal = evaluation.result;
|
|
6736
4947
|
if (!signal || typeof signal === "string") {
|
|
6737
4948
|
const reason = typeof signal === "string" && signal.trim() ? signal : "NO_SIGNAL";
|
|
@@ -6745,12 +4956,12 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
6745
4956
|
timestamp: lastCandle.timestamp,
|
|
6746
4957
|
runtimeConfigId: configId
|
|
6747
4958
|
}),
|
|
6748
|
-
userName
|
|
4959
|
+
userName,
|
|
6749
4960
|
strategy: strategyName,
|
|
6750
4961
|
runtimeConfigId: configId,
|
|
6751
4962
|
runtimeLineage,
|
|
6752
4963
|
symbol,
|
|
6753
|
-
interval
|
|
4964
|
+
interval,
|
|
6754
4965
|
universe,
|
|
6755
4966
|
assetClass: instrument?.assetClass,
|
|
6756
4967
|
accountId,
|
|
@@ -6763,18 +4974,13 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
6763
4974
|
});
|
|
6764
4975
|
continue;
|
|
6765
4976
|
}
|
|
6766
|
-
if (stats)
|
|
6767
|
-
stats.signals += 1;
|
|
6768
|
-
}
|
|
4977
|
+
if (stats) stats.signals += 1;
|
|
6769
4978
|
signal.runtimeConfigId = configId;
|
|
6770
4979
|
signal.runtimeLineage = runtimeLineage;
|
|
6771
4980
|
if (configId && configId !== "config" && !signal.signalId.endsWith(`:${configId}`)) {
|
|
6772
4981
|
signal.signalId = `${signal.signalId}:${configId}`;
|
|
6773
4982
|
}
|
|
6774
|
-
await (0,
|
|
6775
|
-
signal,
|
|
6776
|
-
env: "CRON"
|
|
6777
|
-
});
|
|
4983
|
+
await (0, import_strategies5.enrichSignalWithBinanceMarketContext)({ signal, env: "CRON" });
|
|
6778
4984
|
if (signal.orderStatus === "skipped" && typeof signal.orderSkipReason === "string" && signal.orderSkipReason.trim()) {
|
|
6779
4985
|
recordStrategyReason(
|
|
6780
4986
|
strategyStats,
|
|
@@ -6784,7 +4990,7 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
6784
4990
|
);
|
|
6785
4991
|
}
|
|
6786
4992
|
strategySignals.push(signal);
|
|
6787
|
-
saveRuntimeSignal?.(
|
|
4993
|
+
saveRuntimeSignal?.(userName, signal);
|
|
6788
4994
|
await saveRuntimeSignalEvaluation?.({
|
|
6789
4995
|
evaluationId: buildRuntimeSignalEvaluationId({
|
|
6790
4996
|
strategyName,
|
|
@@ -6792,12 +4998,12 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
6792
4998
|
timestamp: lastCandle.timestamp,
|
|
6793
4999
|
runtimeConfigId: configId
|
|
6794
5000
|
}),
|
|
6795
|
-
userName
|
|
5001
|
+
userName,
|
|
6796
5002
|
strategy: strategyName,
|
|
6797
5003
|
runtimeConfigId: configId,
|
|
6798
5004
|
runtimeLineage,
|
|
6799
5005
|
symbol,
|
|
6800
|
-
interval
|
|
5006
|
+
interval,
|
|
6801
5007
|
universe,
|
|
6802
5008
|
assetClass: instrument?.assetClass,
|
|
6803
5009
|
accountId,
|
|
@@ -6818,259 +5024,383 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
6818
5024
|
}
|
|
6819
5025
|
return strategySignals;
|
|
6820
5026
|
};
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
const
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
|
|
5027
|
+
|
|
5028
|
+
// src/lib/signals/runner.ts
|
|
5029
|
+
var SLOW_SIGNALS_WARNING_MS = 10 * 6e4;
|
|
5030
|
+
var formatDuration2 = (durationMs) => `${(durationMs / 1e3).toFixed(1)}s`;
|
|
5031
|
+
var resolvePositiveInteger = (value, fallback) => {
|
|
5032
|
+
const parsed = Number(value);
|
|
5033
|
+
if (!Number.isFinite(parsed)) {
|
|
5034
|
+
return fallback;
|
|
5035
|
+
}
|
|
5036
|
+
const normalized = Math.floor(parsed);
|
|
5037
|
+
return normalized > 0 ? normalized : fallback;
|
|
5038
|
+
};
|
|
5039
|
+
var resolveNonNegativeInteger = (value, fallback) => {
|
|
5040
|
+
const parsed = Number(value);
|
|
5041
|
+
if (!Number.isFinite(parsed)) {
|
|
5042
|
+
return fallback;
|
|
5043
|
+
}
|
|
5044
|
+
return Math.max(0, Math.floor(parsed));
|
|
5045
|
+
};
|
|
5046
|
+
var createSignalsRunner = (config2) => {
|
|
5047
|
+
const interval = config2.interval;
|
|
5048
|
+
const projectRoot = config2.projectRoot?.trim() || String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
|
|
5049
|
+
const resolveSignalsDaemonMaxLiveBars = (runtimeInterval = interval) => {
|
|
5050
|
+
const intervalMinutes = Number(runtimeInterval);
|
|
5051
|
+
const preloadBars = Math.ceil(
|
|
5052
|
+
import_constants3.SIGNALS_CLI_PRELOAD_DAYS * 24 * 60 / intervalMinutes
|
|
5053
|
+
);
|
|
5054
|
+
return resolvePositiveInteger(
|
|
5055
|
+
process.env.SIGNALS_DAEMON_MAX_LIVE_BARS,
|
|
5056
|
+
preloadBars
|
|
5057
|
+
);
|
|
5058
|
+
};
|
|
5059
|
+
const isSignalsKlineWsEnabled = () => !["0", "false", "off", "no"].includes(
|
|
5060
|
+
String(process.env.SIGNALS_KLINE_WS_ENABLED ?? "true").trim().toLowerCase()
|
|
5061
|
+
);
|
|
5062
|
+
const resolveSignalsKlineWsWaitMs = () => resolveNonNegativeInteger(process.env.SIGNALS_KLINE_WS_WAIT_MS, 1e4);
|
|
5063
|
+
const createDefaultSignalsLifecycle = (runtimeInterval = interval) => createSignalsStrategyLifecycle({
|
|
5064
|
+
intervalMs: Number(runtimeInterval) * 6e4,
|
|
5065
|
+
maxLiveBars: resolveSignalsDaemonMaxLiveBars(runtimeInterval),
|
|
5066
|
+
releaseState: import_strategies6.releaseStrategyReplayCache
|
|
5067
|
+
});
|
|
5068
|
+
const timeOperation2 = (label, operation) => timeOperation(
|
|
5069
|
+
label,
|
|
5070
|
+
operation,
|
|
5071
|
+
(message) => import_logger5.logger.info(import_chalk7.default.gray(message))
|
|
5072
|
+
);
|
|
5073
|
+
const formatSlowSignalsWarning = (params) => [
|
|
5074
|
+
"<b>Slow yarn signals run</b>",
|
|
5075
|
+
`Duration: <b>${formatDuration2(params.durationMs)}</b>`,
|
|
5076
|
+
`Threshold: <b>${formatDuration2(SLOW_SIGNALS_WARNING_MS)}</b>`,
|
|
5077
|
+
`Status: <b>${params.status}</b>`,
|
|
5078
|
+
`Found signals: <b>${params.found}</b>`
|
|
5079
|
+
].join("\n");
|
|
5080
|
+
const resolveSignalsConnectorName = async (value) => {
|
|
5081
|
+
const connectorName = await (0, import_connectors6.resolveConnectorName)(value, projectRoot);
|
|
5082
|
+
if (connectorName) {
|
|
5083
|
+
return connectorName;
|
|
5084
|
+
}
|
|
5085
|
+
import_logger5.logger.warn(
|
|
5086
|
+
'Unknown connector "%s". Fallback to %s.',
|
|
5087
|
+
String(value || "").trim() || String(value),
|
|
5088
|
+
import_connectors6.DEFAULT_CONNECTOR_NAME
|
|
5089
|
+
);
|
|
5090
|
+
return import_connectors6.DEFAULT_CONNECTOR_NAME;
|
|
5091
|
+
};
|
|
5092
|
+
const createSignalsSession2 = async (lifecycle, scope = {}) => {
|
|
5093
|
+
const deployment = config2.deploymentId ? await (0, import_runtimeDeployments.getRuntimeDeployment)(config2.userName, config2.deploymentId) : null;
|
|
5094
|
+
if (config2.deploymentId && !deployment) {
|
|
5095
|
+
throw new Error(`Runtime deployment not found: ${config2.deploymentId}`);
|
|
5096
|
+
}
|
|
5097
|
+
if (deployment && !deployment.enabled) {
|
|
5098
|
+
throw new Error(`Runtime deployment is disabled: ${deployment.id}`);
|
|
5099
|
+
}
|
|
5100
|
+
const requestedRuntimeInterval = scope.interval ?? interval;
|
|
5101
|
+
const runtimeInterval = deployment?.interval ?? requestedRuntimeInterval;
|
|
5102
|
+
const runtimeIntervalMs = Number(runtimeInterval) * 6e4;
|
|
5103
|
+
if (!Number.isFinite(runtimeIntervalMs) || runtimeIntervalMs <= 0) {
|
|
5104
|
+
throw new Error(`Invalid runtime timeframe: ${runtimeInterval}`);
|
|
5105
|
+
}
|
|
5106
|
+
if (deployment && String(deployment.interval) !== String(requestedRuntimeInterval)) {
|
|
5107
|
+
throw new Error(
|
|
5108
|
+
`Deployment ${deployment.id} requires timeframe ${deployment.interval}; received ${requestedRuntimeInterval}`
|
|
5109
|
+
);
|
|
5110
|
+
}
|
|
5111
|
+
const connectorName = await resolveSignalsConnectorName(
|
|
5112
|
+
deployment?.connectorName ?? scope.connectorName ?? config2.connectorName
|
|
5113
|
+
);
|
|
5114
|
+
const universe = deployment?.universe ?? scope.universe ?? config2.universe;
|
|
5115
|
+
const requestedAccountId = deployment?.accountId ?? scope.accountId ?? config2.accountId;
|
|
5116
|
+
const connectorFactory = await (0, import_connectors6.getConnectorCreatorByName)(
|
|
6836
5117
|
connectorName,
|
|
6837
|
-
|
|
6838
|
-
|
|
5118
|
+
projectRoot
|
|
5119
|
+
);
|
|
5120
|
+
if (!connectorFactory) {
|
|
5121
|
+
throw new Error(`Connector "${connectorName}" is not registered`);
|
|
5122
|
+
}
|
|
5123
|
+
const marketConnector = await connectorFactory({
|
|
5124
|
+
userName: config2.userName,
|
|
5125
|
+
universe,
|
|
5126
|
+
accountId: requestedAccountId,
|
|
5127
|
+
deploymentId: deployment?.id
|
|
5128
|
+
});
|
|
5129
|
+
const btcReferences = await loadBtcReferenceConnectors({
|
|
5130
|
+
connectorName,
|
|
5131
|
+
marketConnector,
|
|
5132
|
+
userName: config2.userName,
|
|
5133
|
+
projectRoot,
|
|
5134
|
+
shouldUseDedicatedReferences: universe === "crypto" && connectorName.toLowerCase() === import_connectors6.DEFAULT_CONNECTOR_NAME.toLowerCase(),
|
|
5135
|
+
warn: (message) => import_logger5.logger.warn(message)
|
|
5136
|
+
});
|
|
5137
|
+
return {
|
|
5138
|
+
connectorName,
|
|
5139
|
+
universe,
|
|
5140
|
+
accountId: marketConnector.accountId ?? requestedAccountId,
|
|
5141
|
+
interval: runtimeInterval,
|
|
5142
|
+
intervalMs: runtimeIntervalMs,
|
|
6839
5143
|
deployment,
|
|
5144
|
+
startedAt: Date.now(),
|
|
6840
5145
|
marketConnector,
|
|
6841
5146
|
btcReferences,
|
|
6842
|
-
lifecycle
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
const
|
|
6847
|
-
const
|
|
6848
|
-
|
|
5147
|
+
lifecycle
|
|
5148
|
+
};
|
|
5149
|
+
};
|
|
5150
|
+
const signals2 = async (options = {}) => {
|
|
5151
|
+
const startedAt = Date.now();
|
|
5152
|
+
const signals3 = new Array();
|
|
5153
|
+
const runtimeCloseNotifications = new Array();
|
|
5154
|
+
let status = "completed";
|
|
5155
|
+
let failureMessage;
|
|
5156
|
+
let activeSession;
|
|
5157
|
+
let projectHooks;
|
|
5158
|
+
let afterSignalsHookContext = null;
|
|
5159
|
+
const runtimeSignalEvaluations = createRuntimeSignalEvaluationBuffer();
|
|
5160
|
+
try {
|
|
5161
|
+
const session = options.session ?? await createSignalsSession2(createDefaultSignalsLifecycle());
|
|
5162
|
+
activeSession = session;
|
|
5163
|
+
const persistStrategyState = options.session != null;
|
|
5164
|
+
const {
|
|
5165
|
+
connectorName,
|
|
5166
|
+
universe: sessionUniverse,
|
|
5167
|
+
accountId,
|
|
5168
|
+
deployment,
|
|
6849
5169
|
marketConnector,
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
5170
|
+
btcReferences,
|
|
5171
|
+
lifecycle,
|
|
5172
|
+
interval: interval2,
|
|
5173
|
+
intervalMs
|
|
5174
|
+
} = session;
|
|
5175
|
+
const universe = sessionUniverse ?? marketConnector.universe ?? "crypto";
|
|
5176
|
+
const tickers = await timeOperation2("tickers load", () => {
|
|
5177
|
+
const baseArgs = [
|
|
5178
|
+
marketConnector,
|
|
5179
|
+
config2.tickers || deployment?.tickers?.join(","),
|
|
5180
|
+
config2.exclude,
|
|
5181
|
+
config2.tickersLimit,
|
|
5182
|
+
config2.chunk
|
|
5183
|
+
];
|
|
5184
|
+
return sessionUniverse || accountId || deployment ? (0, import_cli2.getTickers)(...baseArgs, {
|
|
5185
|
+
universe,
|
|
5186
|
+
assetClasses: deployment?.assetClasses
|
|
5187
|
+
}) : (0, import_cli2.getTickers)(...baseArgs);
|
|
5188
|
+
});
|
|
5189
|
+
if (universe === "tradfi" && typeof marketConnector.listInstruments !== "function") {
|
|
5190
|
+
throw new Error("TradFi connector must implement listInstruments");
|
|
5191
|
+
}
|
|
5192
|
+
const instruments = typeof marketConnector.listInstruments === "function" ? await marketConnector.listInstruments({
|
|
6856
5193
|
universe,
|
|
6857
|
-
assetClasses: deployment?.assetClasses
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
5194
|
+
assetClasses: deployment?.assetClasses,
|
|
5195
|
+
symbols: tickers
|
|
5196
|
+
}) : [];
|
|
5197
|
+
const instrumentsBySymbol = new Map(
|
|
5198
|
+
instruments.map((instrument) => [instrument.symbol, instrument])
|
|
5199
|
+
);
|
|
5200
|
+
if (config2.showTickersList) {
|
|
5201
|
+
console.log(import_chalk7.default.gray(JSON.stringify(tickers.sort(), null, 2)));
|
|
5202
|
+
return;
|
|
5203
|
+
}
|
|
5204
|
+
const projectConfig = await (0, import_cli2.loadTradejsConfig)(projectRoot);
|
|
5205
|
+
projectHooks = projectConfig.hooks;
|
|
5206
|
+
const currentTimestamp = (0, import_time3.getTimestamp)();
|
|
5207
|
+
const preloadStart = (0, import_time3.getTimestamp)(import_constants3.SIGNALS_CLI_PRELOAD_DAYS);
|
|
5208
|
+
if (!config2.cacheOnly && session.klineFeed) {
|
|
5209
|
+
const expectedSymbols = universe === "crypto" ? [.../* @__PURE__ */ new Set([...tickers, "BTCUSDT", "ETHUSDT"])] : tickers;
|
|
5210
|
+
session.klineFeed.setSubscriptions(expectedSymbols);
|
|
5211
|
+
const targetTimestamp = Math.floor(currentTimestamp / intervalMs) * intervalMs - intervalMs;
|
|
5212
|
+
const missingSymbols = await timeOperation2(
|
|
5213
|
+
"websocket candle readiness",
|
|
5214
|
+
() => session.klineFeed.waitForClosed({
|
|
5215
|
+
symbols: expectedSymbols,
|
|
5216
|
+
timestamp: targetTimestamp,
|
|
5217
|
+
timeoutMs: resolveSignalsKlineWsWaitMs()
|
|
5218
|
+
})
|
|
5219
|
+
);
|
|
5220
|
+
await session.klineFeed.flush();
|
|
5221
|
+
import_logger5.logger.info(
|
|
5222
|
+
import_chalk7.default.gray(
|
|
5223
|
+
`websocket candles: ready=${expectedSymbols.length - missingSymbols.length}/${expectedSymbols.length} missing=${missingSymbols.length}`
|
|
5224
|
+
)
|
|
5225
|
+
);
|
|
5226
|
+
await updatePrimaryMarketHistory({
|
|
5227
|
+
marketConnector,
|
|
5228
|
+
connectorName,
|
|
5229
|
+
interval: interval2,
|
|
5230
|
+
symbols: missingSymbols,
|
|
5231
|
+
preloadDays: import_constants3.SIGNALS_CLI_PRELOAD_DAYS,
|
|
5232
|
+
universe,
|
|
5233
|
+
log: (message) => import_logger5.logger.info(import_chalk7.default.gray(message))
|
|
5234
|
+
});
|
|
5235
|
+
await updateBtcReferenceHistory({
|
|
5236
|
+
marketConnector,
|
|
5237
|
+
btcReferences,
|
|
5238
|
+
interval: interval2,
|
|
5239
|
+
preloadDays: import_constants3.SIGNALS_CLI_PRELOAD_DAYS,
|
|
5240
|
+
universe,
|
|
5241
|
+
log: (message) => import_logger5.logger.info(import_chalk7.default.gray(message))
|
|
5242
|
+
});
|
|
5243
|
+
} else if (!config2.cacheOnly) {
|
|
5244
|
+
await updateMarketHistoryWithBtcReferences({
|
|
5245
|
+
marketConnector,
|
|
5246
|
+
connectorName,
|
|
5247
|
+
btcReferences,
|
|
5248
|
+
interval: interval2,
|
|
5249
|
+
symbols: tickers,
|
|
5250
|
+
preloadDays: import_constants3.SIGNALS_CLI_PRELOAD_DAYS,
|
|
5251
|
+
universe,
|
|
5252
|
+
log: (message) => import_logger5.logger.info(import_chalk7.default.gray(message))
|
|
5253
|
+
});
|
|
5254
|
+
}
|
|
5255
|
+
await prepareMarketContextForRun({
|
|
5256
|
+
mode: "signals",
|
|
5257
|
+
userName: config2.userName,
|
|
5258
|
+
projectRoot,
|
|
5259
|
+
symbols: tickers,
|
|
5260
|
+
universe,
|
|
5261
|
+
interval: interval2,
|
|
5262
|
+
startMs: currentTimestamp,
|
|
5263
|
+
endMs: currentTimestamp,
|
|
5264
|
+
preloadStartMs: preloadStart,
|
|
5265
|
+
cacheOnly: config2.cacheOnly,
|
|
5266
|
+
log: (message) => import_logger5.logger.info(import_chalk7.default.gray(message))
|
|
5267
|
+
});
|
|
5268
|
+
if (config2.updateOnly) {
|
|
5269
|
+
return;
|
|
5270
|
+
}
|
|
5271
|
+
const [
|
|
5272
|
+
btcBinanceData,
|
|
5273
|
+
btcCoinbaseData,
|
|
5274
|
+
primaryBtcCachedData,
|
|
5275
|
+
primaryEthCachedData
|
|
5276
|
+
] = universe === "crypto" ? await timeOperation2(
|
|
5277
|
+
"reference candles load",
|
|
5278
|
+
() => Promise.all([
|
|
5279
|
+
btcReferences.binance.kline({
|
|
5280
|
+
symbol: "BTCUSDT",
|
|
5281
|
+
start: preloadStart,
|
|
5282
|
+
end: currentTimestamp,
|
|
5283
|
+
cacheOnly: true,
|
|
5284
|
+
interval: interval2
|
|
5285
|
+
}),
|
|
5286
|
+
btcReferences.coinbase.kline({
|
|
5287
|
+
symbol: "BTCUSDT",
|
|
5288
|
+
start: preloadStart,
|
|
5289
|
+
end: currentTimestamp,
|
|
5290
|
+
cacheOnly: true,
|
|
5291
|
+
interval: interval2
|
|
5292
|
+
}),
|
|
5293
|
+
marketConnector.kline({
|
|
5294
|
+
symbol: "BTCUSDT",
|
|
5295
|
+
start: preloadStart,
|
|
5296
|
+
end: currentTimestamp,
|
|
5297
|
+
cacheOnly: true,
|
|
5298
|
+
interval: interval2
|
|
5299
|
+
}),
|
|
5300
|
+
marketConnector.kline({
|
|
5301
|
+
symbol: "ETHUSDT",
|
|
5302
|
+
start: preloadStart,
|
|
5303
|
+
end: currentTimestamp,
|
|
5304
|
+
cacheOnly: true,
|
|
5305
|
+
interval: interval2
|
|
5306
|
+
})
|
|
5307
|
+
])
|
|
5308
|
+
) : [[], [], [], []];
|
|
5309
|
+
const primaryBtcClosedData = getClosedCandlesForInterval(
|
|
5310
|
+
primaryBtcCachedData,
|
|
5311
|
+
currentTimestamp,
|
|
5312
|
+
intervalMs
|
|
6890
5313
|
);
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
|
|
6895
|
-
)
|
|
5314
|
+
const primaryEthClosedData = getClosedCandlesForInterval(
|
|
5315
|
+
primaryEthCachedData,
|
|
5316
|
+
currentTimestamp,
|
|
5317
|
+
intervalMs
|
|
6896
5318
|
);
|
|
6897
|
-
|
|
6898
|
-
|
|
5319
|
+
const primaryEthByTimestamp = new Map(
|
|
5320
|
+
primaryEthClosedData.map((candle) => [candle.timestamp, candle])
|
|
5321
|
+
);
|
|
5322
|
+
const runtimeStrategies = await loadRuntimeStrategies({
|
|
5323
|
+
userName: config2.userName,
|
|
5324
|
+
projectRoot,
|
|
5325
|
+
deployment,
|
|
6899
5326
|
connectorName,
|
|
6900
|
-
interval: interval2,
|
|
6901
|
-
symbols: missingSymbols,
|
|
6902
|
-
preloadDays: import_constants3.SIGNALS_CLI_PRELOAD_DAYS,
|
|
6903
|
-
universe,
|
|
6904
|
-
log: (message) => import_logger4.logger.info(import_chalk7.default.gray(message))
|
|
6905
|
-
});
|
|
6906
|
-
await updateBtcReferenceHistory({
|
|
6907
|
-
marketConnector,
|
|
6908
|
-
btcReferences,
|
|
6909
|
-
interval: interval2,
|
|
6910
|
-
preloadDays: import_constants3.SIGNALS_CLI_PRELOAD_DAYS,
|
|
6911
5327
|
universe,
|
|
6912
|
-
|
|
5328
|
+
accountId,
|
|
5329
|
+
interval: interval2
|
|
6913
5330
|
});
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
5331
|
+
if (!runtimeStrategies.length) {
|
|
5332
|
+
lifecycle.clear();
|
|
5333
|
+
import_logger5.logger.warn(
|
|
5334
|
+
"No strategy configs found by users:%s:strategies:*:config",
|
|
5335
|
+
config2.userName
|
|
5336
|
+
);
|
|
5337
|
+
return;
|
|
5338
|
+
}
|
|
5339
|
+
lifecycle.retain(
|
|
5340
|
+
new Set(
|
|
5341
|
+
tickers.flatMap(
|
|
5342
|
+
(symbol) => runtimeStrategies.map(
|
|
5343
|
+
({ strategyName, configId }) => buildSignalsStrategyLifecycleKey({
|
|
5344
|
+
connectorName,
|
|
5345
|
+
universe: sessionUniverse,
|
|
5346
|
+
accountId,
|
|
5347
|
+
deploymentId: deployment?.id,
|
|
5348
|
+
symbol,
|
|
5349
|
+
interval: interval2,
|
|
5350
|
+
strategyName,
|
|
5351
|
+
configId
|
|
5352
|
+
})
|
|
5353
|
+
)
|
|
5354
|
+
)
|
|
5355
|
+
)
|
|
5356
|
+
);
|
|
5357
|
+
import_logger5.logger.info(
|
|
5358
|
+
import_chalk7.default.yellow(
|
|
5359
|
+
`loaded strategies (user=${config2.userName}): ${runtimeStrategies.map((s) => s.strategyName).join(", ")}`
|
|
5360
|
+
)
|
|
5361
|
+
);
|
|
5362
|
+
afterSignalsHookContext = {
|
|
5363
|
+
connector: marketConnector,
|
|
6917
5364
|
connectorName,
|
|
6918
|
-
|
|
5365
|
+
userName: config2.userName,
|
|
6919
5366
|
interval: interval2,
|
|
6920
|
-
|
|
6921
|
-
|
|
6922
|
-
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
await prepareMarketContextForRun({
|
|
6927
|
-
mode: "signals",
|
|
6928
|
-
userName: flags.user,
|
|
6929
|
-
projectRoot,
|
|
6930
|
-
symbols: tickers,
|
|
6931
|
-
universe,
|
|
6932
|
-
interval: interval2,
|
|
6933
|
-
startMs: currentTimestamp,
|
|
6934
|
-
endMs: currentTimestamp,
|
|
6935
|
-
preloadStartMs: preloadStart,
|
|
6936
|
-
cacheOnly: Boolean(flags.cacheOnly),
|
|
6937
|
-
log: (message) => import_logger4.logger.info(import_chalk7.default.gray(message))
|
|
6938
|
-
});
|
|
6939
|
-
if (flags.updateOnly) {
|
|
6940
|
-
return;
|
|
6941
|
-
}
|
|
6942
|
-
const [
|
|
6943
|
-
btcBinanceData,
|
|
6944
|
-
btcCoinbaseData,
|
|
6945
|
-
primaryBtcCachedData,
|
|
6946
|
-
primaryEthCachedData
|
|
6947
|
-
] = universe === "crypto" ? await timeOperation2(
|
|
6948
|
-
"reference candles load",
|
|
6949
|
-
() => Promise.all([
|
|
6950
|
-
btcReferences.binance.kline({
|
|
6951
|
-
symbol: "BTCUSDT",
|
|
6952
|
-
start: preloadStart,
|
|
6953
|
-
end: currentTimestamp,
|
|
6954
|
-
cacheOnly: true,
|
|
6955
|
-
interval: interval2
|
|
6956
|
-
}),
|
|
6957
|
-
btcReferences.coinbase.kline({
|
|
6958
|
-
symbol: "BTCUSDT",
|
|
6959
|
-
start: preloadStart,
|
|
6960
|
-
end: currentTimestamp,
|
|
6961
|
-
cacheOnly: true,
|
|
6962
|
-
interval: interval2
|
|
6963
|
-
}),
|
|
6964
|
-
marketConnector.kline({
|
|
6965
|
-
symbol: "BTCUSDT",
|
|
6966
|
-
start: preloadStart,
|
|
6967
|
-
end: currentTimestamp,
|
|
6968
|
-
cacheOnly: true,
|
|
6969
|
-
interval: interval2
|
|
6970
|
-
}),
|
|
6971
|
-
marketConnector.kline({
|
|
6972
|
-
symbol: "ETHUSDT",
|
|
6973
|
-
start: preloadStart,
|
|
6974
|
-
end: currentTimestamp,
|
|
6975
|
-
cacheOnly: true,
|
|
6976
|
-
interval: interval2
|
|
6977
|
-
})
|
|
6978
|
-
])
|
|
6979
|
-
) : [[], [], [], []];
|
|
6980
|
-
const primaryBtcClosedData = getClosedCandlesForInterval(
|
|
6981
|
-
primaryBtcCachedData,
|
|
6982
|
-
currentTimestamp,
|
|
6983
|
-
intervalMs2
|
|
6984
|
-
);
|
|
6985
|
-
const primaryEthClosedData = getClosedCandlesForInterval(
|
|
6986
|
-
primaryEthCachedData,
|
|
6987
|
-
currentTimestamp,
|
|
6988
|
-
intervalMs2
|
|
6989
|
-
);
|
|
6990
|
-
const primaryEthByTimestamp = new Map(
|
|
6991
|
-
primaryEthClosedData.map((candle) => [candle.timestamp, candle])
|
|
6992
|
-
);
|
|
6993
|
-
const runtimeStrategies = await loadRuntimeStrategies({
|
|
6994
|
-
userName: flags.user,
|
|
6995
|
-
projectRoot,
|
|
6996
|
-
deployment,
|
|
6997
|
-
connectorName,
|
|
6998
|
-
universe,
|
|
6999
|
-
accountId,
|
|
7000
|
-
interval: interval2
|
|
7001
|
-
});
|
|
7002
|
-
if (!runtimeStrategies.length) {
|
|
7003
|
-
lifecycle.clear();
|
|
7004
|
-
import_logger4.logger.warn(
|
|
7005
|
-
"No strategy configs found by users:%s:strategies:*:config",
|
|
7006
|
-
flags.user
|
|
7007
|
-
);
|
|
7008
|
-
return;
|
|
7009
|
-
}
|
|
7010
|
-
lifecycle.retain(
|
|
7011
|
-
new Set(
|
|
7012
|
-
tickers.flatMap(
|
|
7013
|
-
(symbol) => runtimeStrategies.map(
|
|
7014
|
-
({ strategyName, configId }) => buildSignalsStrategyLifecycleKey({
|
|
7015
|
-
connectorName,
|
|
7016
|
-
universe: sessionUniverse,
|
|
7017
|
-
accountId,
|
|
7018
|
-
deploymentId: deployment?.id,
|
|
7019
|
-
symbol,
|
|
7020
|
-
interval: interval2,
|
|
7021
|
-
strategyName,
|
|
7022
|
-
configId
|
|
7023
|
-
})
|
|
7024
|
-
)
|
|
5367
|
+
tickers: [...tickers],
|
|
5368
|
+
runtimeStrategies: runtimeStrategies.map(
|
|
5369
|
+
({ strategyName, strategyConfig }) => ({
|
|
5370
|
+
strategyName,
|
|
5371
|
+
strategyConfig
|
|
5372
|
+
})
|
|
7025
5373
|
)
|
|
7026
|
-
|
|
7027
|
-
|
|
7028
|
-
|
|
7029
|
-
|
|
7030
|
-
`loaded strategies (user=${flags.user}): ${runtimeStrategies.map((s) => s.strategyName).join(", ")}`
|
|
7031
|
-
)
|
|
7032
|
-
);
|
|
7033
|
-
afterSignalsHookContext = {
|
|
7034
|
-
connector: marketConnector,
|
|
7035
|
-
connectorName,
|
|
7036
|
-
userName: flags.user,
|
|
7037
|
-
interval: interval2,
|
|
7038
|
-
tickers: [...tickers],
|
|
7039
|
-
runtimeStrategies: runtimeStrategies.map(
|
|
7040
|
-
({ strategyName, strategyConfig }) => ({
|
|
7041
|
-
strategyName,
|
|
7042
|
-
strategyConfig
|
|
7043
|
-
})
|
|
7044
|
-
)
|
|
7045
|
-
};
|
|
7046
|
-
const beforeSignalsResult = await invokeBeforeSignalsHooks(
|
|
7047
|
-
projectHooks,
|
|
7048
|
-
afterSignalsHookContext
|
|
7049
|
-
);
|
|
7050
|
-
if (beforeSignalsResult?.abort === true) {
|
|
7051
|
-
import_logger4.logger.info(
|
|
7052
|
-
"signals aborted before ticker evaluation: %s",
|
|
7053
|
-
beforeSignalsResult.reason ?? "PROJECT_BEFORE_SIGNALS_ABORTED"
|
|
5374
|
+
};
|
|
5375
|
+
const beforeSignalsResult = await invokeBeforeSignalsHooks(
|
|
5376
|
+
projectHooks,
|
|
5377
|
+
afterSignalsHookContext
|
|
7054
5378
|
);
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
total: tickers.length,
|
|
7062
|
-
width: 30
|
|
5379
|
+
if (beforeSignalsResult?.abort === true) {
|
|
5380
|
+
import_logger5.logger.info(
|
|
5381
|
+
"signals aborted before ticker evaluation: %s",
|
|
5382
|
+
beforeSignalsResult.reason ?? "PROJECT_BEFORE_SIGNALS_ABORTED"
|
|
5383
|
+
);
|
|
5384
|
+
return;
|
|
7063
5385
|
}
|
|
7064
|
-
|
|
7065
|
-
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
5386
|
+
const strategyStats = createStrategySkipStats(runtimeStrategies);
|
|
5387
|
+
const bar = new import_progress4.default(
|
|
5388
|
+
":current/:total [:bar][:percent] :found :eta(s) :symbol",
|
|
5389
|
+
{
|
|
5390
|
+
total: tickers.length,
|
|
5391
|
+
width: 30
|
|
5392
|
+
}
|
|
5393
|
+
);
|
|
5394
|
+
import_logger5.logger.info(import_chalk7.default.yellow(`tickers: ${tickers.length}`));
|
|
5395
|
+
const signalsParallel = resolvePositiveInteger(config2.parallel, 4);
|
|
5396
|
+
import_logger5.logger.info(import_chalk7.default.yellow(`signal workers: ${signalsParallel}`));
|
|
5397
|
+
const evaluateTicker = createSignalsTickerEvaluator({
|
|
5398
|
+
userName: config2.userName,
|
|
5399
|
+
makeOrders: config2.makeOrders,
|
|
5400
|
+
projectRoot,
|
|
5401
|
+
context: {
|
|
7072
5402
|
connectorName,
|
|
7073
|
-
marketConnector,
|
|
5403
|
+
connector: marketConnector,
|
|
7074
5404
|
btcBinanceData,
|
|
7075
5405
|
btcCoinbaseData,
|
|
7076
5406
|
primaryBtcClosedData,
|
|
@@ -7084,146 +5414,336 @@ var signals = async (options = {}) => {
|
|
|
7084
5414
|
currentTimestamp,
|
|
7085
5415
|
persistStrategyState,
|
|
7086
5416
|
universe,
|
|
7087
|
-
interval2,
|
|
7088
|
-
|
|
5417
|
+
interval: interval2,
|
|
5418
|
+
intervalMs,
|
|
7089
5419
|
accountId,
|
|
7090
|
-
deployment?.id,
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
runtimeSignalEvaluations.
|
|
7094
|
-
runtimeSignalEvaluations.saveSignal
|
|
7095
|
-
);
|
|
7096
|
-
if (strategySignals.length > 0) {
|
|
7097
|
-
signals2.push(...strategySignals);
|
|
5420
|
+
deploymentId: deployment?.id,
|
|
5421
|
+
runtimeScopeUniverse: sessionUniverse,
|
|
5422
|
+
saveRuntimeSignalEvaluation: runtimeSignalEvaluations.save,
|
|
5423
|
+
saveRuntimeSignal: runtimeSignalEvaluations.saveSignal
|
|
7098
5424
|
}
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
|
|
5425
|
+
});
|
|
5426
|
+
await timeOperation2("strategy evaluation", async () => {
|
|
5427
|
+
await (0, import_async3.runWithConcurrency)(tickers, signalsParallel, async (symbol) => {
|
|
5428
|
+
const strategySignals = await evaluateTicker(
|
|
5429
|
+
symbol,
|
|
5430
|
+
instrumentsBySymbol.get(symbol)
|
|
5431
|
+
);
|
|
5432
|
+
if (strategySignals.length > 0) {
|
|
5433
|
+
signals3.push(...strategySignals);
|
|
5434
|
+
}
|
|
5435
|
+
bar.tick(1, {
|
|
5436
|
+
found: import_chalk7.default.cyan(signals3.length),
|
|
5437
|
+
symbol: import_chalk7.default.gray(symbol)
|
|
5438
|
+
});
|
|
7102
5439
|
});
|
|
7103
5440
|
});
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
|
|
7107
|
-
|
|
7108
|
-
|
|
5441
|
+
if (config2.notify) {
|
|
5442
|
+
const telegramSignals = getTelegramDeliverableSignals(signals3);
|
|
5443
|
+
if (!config2.skipScreenshots && telegramSignals.length > 0) {
|
|
5444
|
+
await (0, import_cli2.makeScreenshots)(telegramSignals, interval2, config2.userName);
|
|
5445
|
+
}
|
|
5446
|
+
await (0, import_cli2.sendToTG)(telegramSignals, interval2, config2.userName);
|
|
5447
|
+
await (0, import_cli2.sendRuntimeCloseNotificationsToTG)(
|
|
5448
|
+
runtimeCloseNotifications,
|
|
5449
|
+
config2.userName
|
|
5450
|
+
);
|
|
7109
5451
|
}
|
|
7110
|
-
|
|
7111
|
-
|
|
7112
|
-
|
|
7113
|
-
|
|
5452
|
+
import_logger5.logger.info(
|
|
5453
|
+
JSON.stringify(
|
|
5454
|
+
signals3.map((s) => s.symbol),
|
|
5455
|
+
null,
|
|
5456
|
+
2
|
|
5457
|
+
)
|
|
7114
5458
|
);
|
|
7115
|
-
|
|
7116
|
-
|
|
7117
|
-
|
|
7118
|
-
signals2.map((s) => s.symbol),
|
|
7119
|
-
null,
|
|
7120
|
-
2
|
|
7121
|
-
)
|
|
7122
|
-
);
|
|
7123
|
-
if (flags.showSkipStats) {
|
|
7124
|
-
logStrategySkipStats(runtimeStrategies, strategyStats);
|
|
7125
|
-
}
|
|
7126
|
-
} catch (error) {
|
|
7127
|
-
status = "failed";
|
|
7128
|
-
failureMessage = error?.message || String(error);
|
|
7129
|
-
import_logger4.logger.error(
|
|
7130
|
-
"signals failed: %s",
|
|
7131
|
-
error?.message || String(error)
|
|
7132
|
-
);
|
|
7133
|
-
throw error;
|
|
7134
|
-
} finally {
|
|
7135
|
-
try {
|
|
7136
|
-
await runtimeSignalEvaluations.flush();
|
|
5459
|
+
if (config2.showSkipStats) {
|
|
5460
|
+
logStrategySkipStats(runtimeStrategies, strategyStats);
|
|
5461
|
+
}
|
|
7137
5462
|
} catch (error) {
|
|
7138
|
-
|
|
7139
|
-
|
|
5463
|
+
status = "failed";
|
|
5464
|
+
failureMessage = error?.message || String(error);
|
|
5465
|
+
import_logger5.logger.error(
|
|
5466
|
+
"signals failed: %s",
|
|
7140
5467
|
error?.message || String(error)
|
|
7141
5468
|
);
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
if (activeSession?.deployment) {
|
|
7145
|
-
await (0, import_tradingAccounts2.saveRuntimeDeploymentHeartbeat)(flags.user, {
|
|
7146
|
-
deploymentId: activeSession.deployment.id,
|
|
7147
|
-
status: getSignalsHeartbeatStatus({
|
|
7148
|
-
cycleStatus: status,
|
|
7149
|
-
continuous: options.session != null || Boolean(flags.watch)
|
|
7150
|
-
}),
|
|
7151
|
-
pid: process.pid,
|
|
7152
|
-
startedAt: activeSession.startedAt,
|
|
7153
|
-
lastCycleAt: Date.now(),
|
|
7154
|
-
...failureMessage ? { lastError: failureMessage } : {}
|
|
7155
|
-
});
|
|
7156
|
-
}
|
|
7157
|
-
if (projectHooks && afterSignalsHookContext) {
|
|
5469
|
+
throw error;
|
|
5470
|
+
} finally {
|
|
7158
5471
|
try {
|
|
7159
|
-
await
|
|
7160
|
-
...afterSignalsHookContext,
|
|
7161
|
-
signals: [...signals2],
|
|
7162
|
-
status,
|
|
7163
|
-
durationMs
|
|
7164
|
-
});
|
|
5472
|
+
await runtimeSignalEvaluations.flush();
|
|
7165
5473
|
} catch (error) {
|
|
7166
|
-
|
|
7167
|
-
"
|
|
5474
|
+
import_logger5.logger.error(
|
|
5475
|
+
"runtime signal evaluation flush failed: %s",
|
|
7168
5476
|
error?.message || String(error)
|
|
7169
5477
|
);
|
|
7170
5478
|
}
|
|
5479
|
+
const durationMs = Date.now() - startedAt;
|
|
5480
|
+
if (activeSession?.deployment) {
|
|
5481
|
+
await (0, import_runtimeDeployments.saveRuntimeDeploymentHeartbeat)(config2.userName, {
|
|
5482
|
+
deploymentId: activeSession.deployment.id,
|
|
5483
|
+
status: getSignalsHeartbeatStatus({
|
|
5484
|
+
cycleStatus: status,
|
|
5485
|
+
continuous: options.session != null || Boolean(config2.watch)
|
|
5486
|
+
}),
|
|
5487
|
+
pid: process.pid,
|
|
5488
|
+
startedAt: activeSession.startedAt,
|
|
5489
|
+
lastCycleAt: Date.now(),
|
|
5490
|
+
...failureMessage ? { lastError: failureMessage } : {}
|
|
5491
|
+
});
|
|
5492
|
+
}
|
|
5493
|
+
if (projectHooks && afterSignalsHookContext) {
|
|
5494
|
+
try {
|
|
5495
|
+
await invokeAfterSignalsHooks(projectHooks, {
|
|
5496
|
+
...afterSignalsHookContext,
|
|
5497
|
+
signals: [...signals3],
|
|
5498
|
+
status,
|
|
5499
|
+
durationMs
|
|
5500
|
+
});
|
|
5501
|
+
} catch (error) {
|
|
5502
|
+
import_logger5.logger.error(
|
|
5503
|
+
"afterSignals hook failed: %s",
|
|
5504
|
+
error?.message || String(error)
|
|
5505
|
+
);
|
|
5506
|
+
}
|
|
5507
|
+
}
|
|
5508
|
+
if (config2.notify && durationMs > SLOW_SIGNALS_WARNING_MS) {
|
|
5509
|
+
try {
|
|
5510
|
+
await (0, import_cli2.sendTextToTG)(
|
|
5511
|
+
formatSlowSignalsWarning({
|
|
5512
|
+
durationMs,
|
|
5513
|
+
status,
|
|
5514
|
+
found: signals3.length
|
|
5515
|
+
}),
|
|
5516
|
+
{ userName: config2.userName }
|
|
5517
|
+
);
|
|
5518
|
+
} catch (error) {
|
|
5519
|
+
import_logger5.logger.error(
|
|
5520
|
+
"slow signals warning failed: %s",
|
|
5521
|
+
error?.message || String(error)
|
|
5522
|
+
);
|
|
5523
|
+
}
|
|
5524
|
+
}
|
|
5525
|
+
import_logger5.logger.info(
|
|
5526
|
+
import_chalk7.default.yellow(
|
|
5527
|
+
`signals ${status} in ${formatDuration2(durationMs)} (found=${signals3.length})`
|
|
5528
|
+
)
|
|
5529
|
+
);
|
|
5530
|
+
import_logger5.logger.info("");
|
|
5531
|
+
import_logger5.logger.info("");
|
|
5532
|
+
import_logger5.logger.info("");
|
|
5533
|
+
}
|
|
5534
|
+
};
|
|
5535
|
+
const loadConfiguredSignalsScopes = async (deployment) => {
|
|
5536
|
+
const configuredStrategies = await loadRuntimeStrategies({
|
|
5537
|
+
userName: config2.userName,
|
|
5538
|
+
projectRoot,
|
|
5539
|
+
deployment,
|
|
5540
|
+
connectorName: config2.connectorName
|
|
5541
|
+
});
|
|
5542
|
+
const connectorName = await resolveSignalsConnectorName(
|
|
5543
|
+
deployment?.connectorName ?? config2.connectorName
|
|
5544
|
+
);
|
|
5545
|
+
const scopes = /* @__PURE__ */ new Map();
|
|
5546
|
+
for (const strategy of configuredStrategies) {
|
|
5547
|
+
const key = [
|
|
5548
|
+
connectorName,
|
|
5549
|
+
strategy.universe,
|
|
5550
|
+
strategy.accountId ?? "default",
|
|
5551
|
+
strategy.interval
|
|
5552
|
+
].join(":");
|
|
5553
|
+
scopes.set(key, {
|
|
5554
|
+
connectorName,
|
|
5555
|
+
universe: strategy.universe,
|
|
5556
|
+
accountId: strategy.accountId,
|
|
5557
|
+
interval: strategy.interval
|
|
5558
|
+
});
|
|
5559
|
+
}
|
|
5560
|
+
return scopes;
|
|
5561
|
+
};
|
|
5562
|
+
const hasExplicitSignalsScope = () => Boolean(config2.hasExplicitScope);
|
|
5563
|
+
const signalsConfiguredScopesOnce2 = async () => {
|
|
5564
|
+
if (config2.updateOnly || config2.showTickersList || config2.deploymentId || hasExplicitSignalsScope()) {
|
|
5565
|
+
return signals2();
|
|
7171
5566
|
}
|
|
7172
|
-
|
|
5567
|
+
const scopes = await loadConfiguredSignalsScopes();
|
|
5568
|
+
if (!scopes.size) return signals2();
|
|
5569
|
+
for (const scope of scopes.values()) {
|
|
5570
|
+
const session = await createSignalsSession2(
|
|
5571
|
+
createDefaultSignalsLifecycle(scope.interval),
|
|
5572
|
+
scope
|
|
5573
|
+
);
|
|
7173
5574
|
try {
|
|
7174
|
-
await (
|
|
7175
|
-
|
|
7176
|
-
|
|
7177
|
-
|
|
7178
|
-
found: signals2.length
|
|
7179
|
-
}),
|
|
7180
|
-
{ userName: flags.user }
|
|
7181
|
-
);
|
|
7182
|
-
} catch (error) {
|
|
7183
|
-
import_logger4.logger.error(
|
|
7184
|
-
"slow signals warning failed: %s",
|
|
7185
|
-
error?.message || String(error)
|
|
7186
|
-
);
|
|
5575
|
+
await signals2({ session });
|
|
5576
|
+
} finally {
|
|
5577
|
+
await session.klineFeed?.close();
|
|
5578
|
+
session.lifecycle.clear();
|
|
7187
5579
|
}
|
|
7188
5580
|
}
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7192
|
-
|
|
5581
|
+
};
|
|
5582
|
+
const signalsDaemon2 = async () => {
|
|
5583
|
+
if (config2.updateOnly || config2.showTickersList) {
|
|
5584
|
+
throw new Error(
|
|
5585
|
+
"Signals daemon does not support updateOnly or showTickersList mode"
|
|
5586
|
+
);
|
|
5587
|
+
}
|
|
5588
|
+
const abortController = new AbortController();
|
|
5589
|
+
const daemonDeployment = config2.deploymentId ? await (0, import_runtimeDeployments.getRuntimeDeployment)(config2.userName, config2.deploymentId) : null;
|
|
5590
|
+
if (config2.deploymentId && !daemonDeployment) {
|
|
5591
|
+
throw new Error(`Runtime deployment not found: ${config2.deploymentId}`);
|
|
5592
|
+
}
|
|
5593
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
5594
|
+
const lastBoundaryByScope = /* @__PURE__ */ new Map();
|
|
5595
|
+
const stop = (signalName) => {
|
|
5596
|
+
import_logger5.logger.info("signals daemon stopping by %s", signalName);
|
|
5597
|
+
abortController.abort();
|
|
5598
|
+
};
|
|
5599
|
+
const stopOnSigint = () => stop("SIGINT");
|
|
5600
|
+
const stopOnSigterm = () => stop("SIGTERM");
|
|
5601
|
+
process.once("SIGINT", stopOnSigint);
|
|
5602
|
+
process.once("SIGTERM", stopOnSigterm);
|
|
5603
|
+
import_logger5.logger.info(
|
|
5604
|
+
"signals daemon started (config-driven scopes, fallback interval=%s)",
|
|
5605
|
+
interval
|
|
7193
5606
|
);
|
|
7194
|
-
|
|
7195
|
-
|
|
7196
|
-
|
|
7197
|
-
|
|
7198
|
-
|
|
7199
|
-
|
|
7200
|
-
|
|
7201
|
-
|
|
7202
|
-
|
|
7203
|
-
|
|
7204
|
-
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
|
|
7208
|
-
|
|
7209
|
-
|
|
7210
|
-
|
|
7211
|
-
|
|
7212
|
-
|
|
7213
|
-
|
|
7214
|
-
|
|
7215
|
-
|
|
7216
|
-
|
|
7217
|
-
|
|
7218
|
-
|
|
7219
|
-
|
|
7220
|
-
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
5607
|
+
try {
|
|
5608
|
+
await runSignalsDaemon({
|
|
5609
|
+
intervalMs: 6e4,
|
|
5610
|
+
settleDelayMs: resolveNonNegativeInteger(config2.settleDelayMs, 5e3),
|
|
5611
|
+
signal: abortController.signal,
|
|
5612
|
+
runCycle: async () => {
|
|
5613
|
+
const scopes = await loadConfiguredSignalsScopes(daemonDeployment);
|
|
5614
|
+
for (const [key, staleSession] of sessions) {
|
|
5615
|
+
if (scopes.has(key)) continue;
|
|
5616
|
+
await staleSession.klineFeed?.close();
|
|
5617
|
+
staleSession.lifecycle.clear();
|
|
5618
|
+
sessions.delete(key);
|
|
5619
|
+
lastBoundaryByScope.delete(key);
|
|
5620
|
+
}
|
|
5621
|
+
for (const [key, scope] of scopes) {
|
|
5622
|
+
const scopeIntervalMs = Number(scope.interval) * 6e4;
|
|
5623
|
+
const boundary = Math.floor(Date.now() / scopeIntervalMs) * scopeIntervalMs;
|
|
5624
|
+
if (lastBoundaryByScope.get(key) === boundary) continue;
|
|
5625
|
+
let session = sessions.get(key);
|
|
5626
|
+
if (!session) {
|
|
5627
|
+
session = await createSignalsSession2(
|
|
5628
|
+
createDefaultSignalsLifecycle(scope.interval),
|
|
5629
|
+
scope
|
|
5630
|
+
);
|
|
5631
|
+
sessions.set(key, session);
|
|
5632
|
+
}
|
|
5633
|
+
if (!session.klineFeed && isSignalsKlineWsEnabled() && session.connectorName.toLowerCase() === "bybit") {
|
|
5634
|
+
session.klineFeed = await createSignalsKlineFeed({
|
|
5635
|
+
config: {
|
|
5636
|
+
userName: config2.userName,
|
|
5637
|
+
universe: session.universe,
|
|
5638
|
+
accountId: session.accountId,
|
|
5639
|
+
deploymentId: session.deployment?.id
|
|
5640
|
+
},
|
|
5641
|
+
interval: session.interval,
|
|
5642
|
+
universe: session.universe
|
|
5643
|
+
});
|
|
5644
|
+
import_logger5.logger.info(
|
|
5645
|
+
"Bybit websocket candle feed enabled (account=%s, universe=%s, interval=%s)",
|
|
5646
|
+
session.accountId ?? "default",
|
|
5647
|
+
session.universe,
|
|
5648
|
+
session.interval
|
|
5649
|
+
);
|
|
5650
|
+
}
|
|
5651
|
+
try {
|
|
5652
|
+
await signals2({ session });
|
|
5653
|
+
lastBoundaryByScope.set(key, boundary);
|
|
5654
|
+
} catch (error) {
|
|
5655
|
+
await session.klineFeed?.close();
|
|
5656
|
+
session.lifecycle.clear();
|
|
5657
|
+
sessions.delete(key);
|
|
5658
|
+
throw error;
|
|
5659
|
+
}
|
|
5660
|
+
}
|
|
5661
|
+
const memory = process.memoryUsage();
|
|
5662
|
+
const stateKeys = [...sessions.values()].reduce(
|
|
5663
|
+
(sum, session) => sum + session.lifecycle.size(),
|
|
5664
|
+
0
|
|
5665
|
+
);
|
|
5666
|
+
import_logger5.logger.info(
|
|
5667
|
+
"signals daemon resources: rss=%sMB heapUsed=%sMB heapTotal=%sMB stateKeys=%s scopes=%s",
|
|
5668
|
+
(memory.rss / 1024 / 1024).toFixed(1),
|
|
5669
|
+
(memory.heapUsed / 1024 / 1024).toFixed(1),
|
|
5670
|
+
(memory.heapTotal / 1024 / 1024).toFixed(1),
|
|
5671
|
+
stateKeys,
|
|
5672
|
+
sessions.size
|
|
5673
|
+
);
|
|
5674
|
+
},
|
|
5675
|
+
onCycleError: (error) => {
|
|
5676
|
+
import_logger5.logger.error(
|
|
5677
|
+
"signals daemon cycle failed: %s",
|
|
5678
|
+
error?.message || String(error)
|
|
5679
|
+
);
|
|
5680
|
+
}
|
|
5681
|
+
});
|
|
5682
|
+
} finally {
|
|
5683
|
+
process.removeListener("SIGINT", stopOnSigint);
|
|
5684
|
+
process.removeListener("SIGTERM", stopOnSigterm);
|
|
5685
|
+
for (const session of sessions.values()) {
|
|
5686
|
+
await session.klineFeed?.close();
|
|
5687
|
+
session.lifecycle.clear();
|
|
5688
|
+
if (session.deployment) {
|
|
5689
|
+
await (0, import_runtimeDeployments.saveRuntimeDeploymentHeartbeat)(config2.userName, {
|
|
5690
|
+
deploymentId: session.deployment.id,
|
|
5691
|
+
status: "stopped",
|
|
5692
|
+
pid: process.pid,
|
|
5693
|
+
startedAt: session.startedAt,
|
|
5694
|
+
lastCycleAt: Date.now()
|
|
5695
|
+
});
|
|
5696
|
+
}
|
|
5697
|
+
}
|
|
5698
|
+
}
|
|
5699
|
+
};
|
|
5700
|
+
return {
|
|
5701
|
+
createSession: createSignalsSession2,
|
|
5702
|
+
runCycle: signals2,
|
|
5703
|
+
runConfiguredScopesOnce: signalsConfiguredScopesOnce2,
|
|
5704
|
+
runDaemon: signalsDaemon2
|
|
5705
|
+
};
|
|
7225
5706
|
};
|
|
7226
|
-
|
|
5707
|
+
|
|
5708
|
+
// src/scripts/signals.ts
|
|
5709
|
+
import_args.default.option(["t", "tickers"], "Selected tickers");
|
|
5710
|
+
import_args.default.option(["e", "exclude"], "Exclude tickers from tests");
|
|
5711
|
+
import_args.default.option(["l", "tickersLimit"], "Tickers limit");
|
|
5712
|
+
import_args.default.option(["f", "timeframe"], "Timeframe", 15);
|
|
5713
|
+
import_args.default.option(["m", "makeOrders"], "Make orders");
|
|
5714
|
+
import_args.default.option(["N", "notify"], "Send message in Telegram", false);
|
|
5715
|
+
import_args.default.option(["S", "skipScreenshots"], "Skip screenshot generation", false);
|
|
5716
|
+
import_args.default.option(["u", "updateOnly"], "Only update tickers history", false);
|
|
5717
|
+
import_args.default.option(["C", "cacheOnly"], "Do not update tickers history", false);
|
|
5718
|
+
import_args.default.option(["L", "showTickersList"], "Just show only ticker list", false);
|
|
5719
|
+
import_args.default.option(
|
|
5720
|
+
["p", "parallel"],
|
|
5721
|
+
"Signal evaluation worker count",
|
|
5722
|
+
Number(process.env.SIGNALS_PARALLEL || 4)
|
|
5723
|
+
);
|
|
5724
|
+
import_args.default.option(
|
|
5725
|
+
["R", "showSkipStats"],
|
|
5726
|
+
"Show aggregated skip stats by strategy",
|
|
5727
|
+
false
|
|
5728
|
+
);
|
|
5729
|
+
import_args.default.option(["c", "chunk"], "Split by chunks, ex. 1/3");
|
|
5730
|
+
import_args.default.option(["U", "user"], "Use user confg", "root");
|
|
5731
|
+
import_args.default.option(["w", "watch"], "Keep signals running on candle boundaries", false);
|
|
5732
|
+
import_args.default.option(
|
|
5733
|
+
["d", "settleDelayMs"],
|
|
5734
|
+
"Delay after candle close before a daemon cycle",
|
|
5735
|
+
Number(process.env.SIGNALS_DAEMON_SETTLE_DELAY_MS || 5e3)
|
|
5736
|
+
);
|
|
5737
|
+
import_args.default.option(
|
|
5738
|
+
["o", "connector"],
|
|
5739
|
+
"Connector provider or name for signals (e.g. bybit, binance, coinbase, custom)",
|
|
5740
|
+
"bybit"
|
|
5741
|
+
);
|
|
5742
|
+
import_args.default.option(["V", "universe"], "Market universe (crypto or tradfi)", "crypto");
|
|
5743
|
+
import_args.default.option(["A", "account"], "Trading account id");
|
|
5744
|
+
import_args.default.option(["D", "deployment"], "Runtime deployment id");
|
|
5745
|
+
var flags = import_args.default.parse(process.argv);
|
|
5746
|
+
var hasExplicitScope = process.argv.some(
|
|
7227
5747
|
(argument) => [
|
|
7228
5748
|
"-f",
|
|
7229
5749
|
"--timeframe",
|
|
@@ -7233,148 +5753,38 @@ var hasExplicitSignalsScope = () => process.argv.some(
|
|
|
7233
5753
|
"--account",
|
|
7234
5754
|
"-D",
|
|
7235
5755
|
"--deployment"
|
|
7236
|
-
].some(
|
|
7237
|
-
(option) => argument === option || argument.startsWith(`${option}=`)
|
|
7238
|
-
)
|
|
5756
|
+
].some((option) => argument === option || argument.startsWith(`${option}=`))
|
|
7239
5757
|
);
|
|
7240
|
-
var
|
|
7241
|
-
|
|
7242
|
-
|
|
7243
|
-
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
|
|
7252
|
-
|
|
7253
|
-
|
|
7254
|
-
|
|
7255
|
-
|
|
7256
|
-
|
|
7257
|
-
|
|
7258
|
-
|
|
7259
|
-
|
|
7260
|
-
|
|
7261
|
-
|
|
7262
|
-
|
|
7263
|
-
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7268
|
-
|
|
7269
|
-
|
|
7270
|
-
const sessions = /* @__PURE__ */ new Map();
|
|
7271
|
-
const lastBoundaryByScope = /* @__PURE__ */ new Map();
|
|
7272
|
-
const stop = (signalName) => {
|
|
7273
|
-
import_logger4.logger.info("signals daemon stopping by %s", signalName);
|
|
7274
|
-
abortController.abort();
|
|
7275
|
-
};
|
|
7276
|
-
const stopOnSigint = () => stop("SIGINT");
|
|
7277
|
-
const stopOnSigterm = () => stop("SIGTERM");
|
|
7278
|
-
process.once("SIGINT", stopOnSigint);
|
|
7279
|
-
process.once("SIGTERM", stopOnSigterm);
|
|
7280
|
-
import_logger4.logger.info(
|
|
7281
|
-
"signals daemon started (config-driven scopes, fallback interval=%s)",
|
|
7282
|
-
interval
|
|
7283
|
-
);
|
|
7284
|
-
try {
|
|
7285
|
-
await runSignalsDaemon({
|
|
7286
|
-
intervalMs: 6e4,
|
|
7287
|
-
settleDelayMs: resolveNonNegativeInteger(flags.settleDelayMs, 5e3),
|
|
7288
|
-
signal: abortController.signal,
|
|
7289
|
-
runCycle: async () => {
|
|
7290
|
-
const scopes = await loadConfiguredSignalsScopes(daemonDeployment);
|
|
7291
|
-
for (const [key, staleSession] of sessions) {
|
|
7292
|
-
if (scopes.has(key)) continue;
|
|
7293
|
-
await staleSession.klineFeed?.close();
|
|
7294
|
-
staleSession.lifecycle.clear();
|
|
7295
|
-
sessions.delete(key);
|
|
7296
|
-
lastBoundaryByScope.delete(key);
|
|
7297
|
-
}
|
|
7298
|
-
for (const [key, scope] of scopes) {
|
|
7299
|
-
const scopeIntervalMs = Number(scope.interval) * 6e4;
|
|
7300
|
-
const boundary = Math.floor(Date.now() / scopeIntervalMs) * scopeIntervalMs;
|
|
7301
|
-
if (lastBoundaryByScope.get(key) === boundary) continue;
|
|
7302
|
-
let session = sessions.get(key);
|
|
7303
|
-
if (!session) {
|
|
7304
|
-
session = await createSignalsSession(
|
|
7305
|
-
createDefaultSignalsLifecycle(scope.interval),
|
|
7306
|
-
scope
|
|
7307
|
-
);
|
|
7308
|
-
sessions.set(key, session);
|
|
7309
|
-
}
|
|
7310
|
-
if (!session.klineFeed && isSignalsKlineWsEnabled() && session.connectorName.toLowerCase() === "bybit") {
|
|
7311
|
-
session.klineFeed = await createSignalsKlineFeed({
|
|
7312
|
-
config: {
|
|
7313
|
-
userName: flags.user,
|
|
7314
|
-
universe: session.universe,
|
|
7315
|
-
accountId: session.accountId,
|
|
7316
|
-
deploymentId: session.deployment?.id
|
|
7317
|
-
},
|
|
7318
|
-
interval: session.interval,
|
|
7319
|
-
universe: session.universe
|
|
7320
|
-
});
|
|
7321
|
-
import_logger4.logger.info(
|
|
7322
|
-
"Bybit websocket candle feed enabled (account=%s, universe=%s, interval=%s)",
|
|
7323
|
-
session.accountId ?? "default",
|
|
7324
|
-
session.universe,
|
|
7325
|
-
session.interval
|
|
7326
|
-
);
|
|
7327
|
-
}
|
|
7328
|
-
try {
|
|
7329
|
-
await signals({ session });
|
|
7330
|
-
lastBoundaryByScope.set(key, boundary);
|
|
7331
|
-
} catch (error) {
|
|
7332
|
-
await session.klineFeed?.close();
|
|
7333
|
-
session.lifecycle.clear();
|
|
7334
|
-
sessions.delete(key);
|
|
7335
|
-
throw error;
|
|
7336
|
-
}
|
|
7337
|
-
}
|
|
7338
|
-
const memory = process.memoryUsage();
|
|
7339
|
-
const stateKeys = [...sessions.values()].reduce(
|
|
7340
|
-
(sum, session) => sum + session.lifecycle.size(),
|
|
7341
|
-
0
|
|
7342
|
-
);
|
|
7343
|
-
import_logger4.logger.info(
|
|
7344
|
-
"signals daemon resources: rss=%sMB heapUsed=%sMB heapTotal=%sMB stateKeys=%s scopes=%s",
|
|
7345
|
-
(memory.rss / 1024 / 1024).toFixed(1),
|
|
7346
|
-
(memory.heapUsed / 1024 / 1024).toFixed(1),
|
|
7347
|
-
(memory.heapTotal / 1024 / 1024).toFixed(1),
|
|
7348
|
-
stateKeys,
|
|
7349
|
-
sessions.size
|
|
7350
|
-
);
|
|
7351
|
-
},
|
|
7352
|
-
onCycleError: (error) => {
|
|
7353
|
-
import_logger4.logger.error(
|
|
7354
|
-
"signals daemon cycle failed: %s",
|
|
7355
|
-
error?.message || String(error)
|
|
7356
|
-
);
|
|
7357
|
-
}
|
|
7358
|
-
});
|
|
7359
|
-
} finally {
|
|
7360
|
-
process.removeListener("SIGINT", stopOnSigint);
|
|
7361
|
-
process.removeListener("SIGTERM", stopOnSigterm);
|
|
7362
|
-
for (const session of sessions.values()) {
|
|
7363
|
-
await session.klineFeed?.close();
|
|
7364
|
-
session.lifecycle.clear();
|
|
7365
|
-
if (session.deployment) {
|
|
7366
|
-
await (0, import_tradingAccounts2.saveRuntimeDeploymentHeartbeat)(flags.user, {
|
|
7367
|
-
deploymentId: session.deployment.id,
|
|
7368
|
-
status: "stopped",
|
|
7369
|
-
pid: process.pid,
|
|
7370
|
-
startedAt: session.startedAt,
|
|
7371
|
-
lastCycleAt: Date.now()
|
|
7372
|
-
});
|
|
7373
|
-
}
|
|
7374
|
-
}
|
|
7375
|
-
}
|
|
7376
|
-
};
|
|
7377
|
-
var main = () => flags.watch ? signalsDaemon() : signalsConfiguredScopesOnce();
|
|
5758
|
+
var config = {
|
|
5759
|
+
projectRoot: String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd(),
|
|
5760
|
+
userName: String(flags.user || "root"),
|
|
5761
|
+
interval: String(flags.timeframe ?? 15),
|
|
5762
|
+
connectorName: String(flags.connector || "bybit"),
|
|
5763
|
+
universe: flags.universe,
|
|
5764
|
+
accountId: flags.account ? String(flags.account) : void 0,
|
|
5765
|
+
deploymentId: flags.deployment ? String(flags.deployment) : void 0,
|
|
5766
|
+
tickers: flags.tickers,
|
|
5767
|
+
exclude: flags.exclude,
|
|
5768
|
+
tickersLimit: flags.tickersLimit,
|
|
5769
|
+
chunk: flags.chunk,
|
|
5770
|
+
makeOrders: Boolean(flags.makeOrders),
|
|
5771
|
+
notify: Boolean(flags.notify),
|
|
5772
|
+
skipScreenshots: Boolean(flags.skipScreenshots),
|
|
5773
|
+
updateOnly: Boolean(flags.updateOnly),
|
|
5774
|
+
cacheOnly: Boolean(flags.cacheOnly),
|
|
5775
|
+
showTickersList: Boolean(flags.showTickersList),
|
|
5776
|
+
showSkipStats: Boolean(flags.showSkipStats),
|
|
5777
|
+
parallel: flags.parallel,
|
|
5778
|
+
watch: Boolean(flags.watch),
|
|
5779
|
+
settleDelayMs: flags.settleDelayMs,
|
|
5780
|
+
hasExplicitScope
|
|
5781
|
+
};
|
|
5782
|
+
var runner = createSignalsRunner(config);
|
|
5783
|
+
var createSignalsSession = runner.createSession;
|
|
5784
|
+
var signals = runner.runCycle;
|
|
5785
|
+
var signalsConfiguredScopesOnce = runner.runConfiguredScopesOnce;
|
|
5786
|
+
var signalsDaemon = runner.runDaemon;
|
|
5787
|
+
var main = () => config.watch ? signalsDaemon() : signalsConfiguredScopesOnce();
|
|
7378
5788
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7379
5789
|
0 && (module.exports = {
|
|
7380
5790
|
createSignalsSession,
|