@tradejs/cli 1.0.9 → 1.0.10

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.
Files changed (76) hide show
  1. package/dist/cli.js +29497 -13537
  2. package/dist/lib/aiPocketSearch.js +1316 -0
  3. package/dist/lib/aiTrainCharts.js +711 -0
  4. package/dist/lib/aiTrainDataset.js +40 -0
  5. package/dist/lib/aiTrainEvaluationDump.js +76 -0
  6. package/dist/lib/aiTrainMetrics.js +148 -8
  7. package/dist/lib/aiTrainOptions.js +130 -0
  8. package/dist/lib/aiTrainQuarantine.js +199 -0
  9. package/dist/lib/aiTrainResearch.js +467 -0
  10. package/dist/lib/binanceMarketContextBackfill.js +841 -0
  11. package/dist/lib/binanceMarketData.js +392 -0
  12. package/dist/lib/coinMarketCapContextBackfill.js +1088 -0
  13. package/dist/lib/continuity.js +60 -0
  14. package/dist/lib/derivativesContextBackfill.js +490 -77
  15. package/dist/lib/executionCalibration.js +705 -0
  16. package/dist/lib/marketContextPrepare.js +4403 -0
  17. package/dist/lib/paritySummary.js +101 -0
  18. package/dist/lib/runBot.js +1 -0
  19. package/dist/lib/runEnvironment.js +2254 -0
  20. package/dist/lib/runFormatting.js +1657 -0
  21. package/dist/lib/runtimeDebugEvidence.js +526 -0
  22. package/dist/lib/runtimeModeConfig.js +53 -0
  23. package/dist/lib/runtimeParity.js +88 -11
  24. package/dist/lib/runtimeParityDetails.js +751 -0
  25. package/dist/lib/runtimeRedis.js +157 -0
  26. package/dist/lib/runtimeSignalsLoader.js +40 -6
  27. package/dist/lib/runtimeSignalsStorage.js +45 -22
  28. package/dist/lib/runtimeStrategyBacktest.js +134 -0
  29. package/dist/lib/runtimeTradeSync.js +263 -0
  30. package/dist/lib/telegramReports.js +9 -0
  31. package/dist/lib/tickerUniverseCache.js +116 -0
  32. package/dist/lib/timeWindow.js +3 -3
  33. package/dist/scripts/agentRun.js +14 -8
  34. package/dist/scripts/aiExport.js +1721 -7
  35. package/dist/scripts/aiExportSelect.js +16 -4
  36. package/dist/scripts/aiPocketSearch.js +4190 -0
  37. package/dist/scripts/aiTrain.js +1866 -87
  38. package/dist/scripts/backtest.js +4509 -818
  39. package/dist/scripts/binanceMarketIngest.js +565 -0
  40. package/dist/scripts/bot.js +16 -2
  41. package/dist/scripts/candlesMigrateProvider.js +32 -22
  42. package/dist/scripts/cleanDir.js +15 -2
  43. package/dist/scripts/cleanRedis.js +15 -2
  44. package/dist/scripts/cleanTests.js +38 -2
  45. package/dist/scripts/cleanupMarketContext.js +69 -0
  46. package/dist/scripts/continuity.js +148 -67
  47. package/dist/scripts/derivativesIngest.js +14 -4
  48. package/dist/scripts/derivativesIngestCoinalyzeAll.js +14 -4
  49. package/dist/scripts/doctor.js +14 -4
  50. package/dist/scripts/executionCalibration.js +792 -0
  51. package/dist/scripts/infraCommon.js +10 -0
  52. package/dist/scripts/infraDown.js +14 -4
  53. package/dist/scripts/infraInit.js +24 -4
  54. package/dist/scripts/infraUp.js +14 -4
  55. package/dist/scripts/marketWs.js +222 -0
  56. package/dist/scripts/migration.js +15 -2
  57. package/dist/scripts/mlExport.js +1698 -10
  58. package/dist/scripts/mlExportSelect.js +16 -4
  59. package/dist/scripts/mlInspect.js +13 -3
  60. package/dist/scripts/mlTrainLatestSelect.js +14 -4
  61. package/dist/scripts/replay.js +8824 -0
  62. package/dist/scripts/replayRunner.js +8827 -0
  63. package/dist/scripts/replayRuntimeEvidence.js +868 -0
  64. package/dist/scripts/researchAuto.js +286 -59
  65. package/dist/scripts/results.js +3 -3
  66. package/dist/scripts/runtimeEvidence.js +605 -0
  67. package/dist/scripts/runtimeParity.js +6362 -1043
  68. package/dist/scripts/serverHealth.js +588 -0
  69. package/dist/scripts/signals.js +5590 -511
  70. package/dist/scripts/signalsDaemon.js +6167 -0
  71. package/dist/scripts/signalsSummary.js +833 -248
  72. package/dist/scripts/test-ml.js +25 -3
  73. package/dist/scripts/test.js +26 -1
  74. package/dist/scripts/user-add.js +15 -2
  75. package/dist/workers/testerWorker.js +130 -21
  76. package/package.json +18 -12
@@ -0,0 +1,565 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/scripts/binanceMarketIngest.ts
31
+ var binanceMarketIngest_exports = {};
32
+ __export(binanceMarketIngest_exports, {
33
+ main: () => main
34
+ });
35
+ module.exports = __toCommonJS(binanceMarketIngest_exports);
36
+ var import_config = require("dotenv/config");
37
+ var import_args = __toESM(require("args"));
38
+ var import_chalk = __toESM(require("chalk"));
39
+ var import_connectors = require("@tradejs/connectors");
40
+ var import_timescale = require("@tradejs/infra/timescale");
41
+
42
+ // src/lib/binanceMarketData.ts
43
+ var MARKET_FEATURE_INTERVAL_MS = {
44
+ "1m": 6e4,
45
+ "5m": 3e5,
46
+ "15m": 9e5,
47
+ "1h": 36e5
48
+ };
49
+ var STABLE_QUOTE_SYMBOLS = /* @__PURE__ */ new Set([
50
+ "USDCUSDT",
51
+ "FDUSDUSDT",
52
+ "TUSDUSDT",
53
+ "BUSDUSDT",
54
+ "USDPUSDT",
55
+ "DAIUSDT"
56
+ ]);
57
+ var safeDivide = (num, den) => Number.isFinite(num) && Number.isFinite(den) && den !== 0 ? num / den : null;
58
+ var mean = (values) => values.length ? values.reduce((sum, value) => sum + value, 0) / values.length : null;
59
+ var standardDeviation = (values) => {
60
+ const avg = mean(values);
61
+ if (avg == null || values.length < 2) return null;
62
+ const variance = values.reduce((sum, value) => sum + (value - avg) ** 2, 0) / values.length;
63
+ return Math.sqrt(variance);
64
+ };
65
+ var buildPrefixSum = (values) => {
66
+ const prefix = [0];
67
+ for (const value of values) prefix.push(prefix[prefix.length - 1] + value);
68
+ return prefix;
69
+ };
70
+ var sumPrefixRange = (prefix, startIndex, endIndexInclusive) => {
71
+ if (endIndexInclusive < startIndex) return 0;
72
+ const start = Math.max(0, startIndex);
73
+ const end = Math.min(prefix.length - 2, endIndexInclusive);
74
+ if (end < start) return 0;
75
+ return prefix[end + 1] - prefix[start];
76
+ };
77
+ var windowReturn = (candles, index, lookbackBars) => {
78
+ const previous = candles[index - lookbackBars];
79
+ const current = candles[index];
80
+ return previous && previous.close > 0 ? (current.close - previous.close) / previous.close : null;
81
+ };
82
+ var classifyBtcAltRegime = ({
83
+ btcReturn24h,
84
+ altBasketReturn24h,
85
+ btcVsAltReturn24h
86
+ }) => {
87
+ if (btcReturn24h == null || altBasketReturn24h == null || btcVsAltReturn24h == null) {
88
+ return "unknown";
89
+ }
90
+ if (btcReturn24h < -0.015 && altBasketReturn24h < -0.025) {
91
+ return "risk_off";
92
+ }
93
+ if (btcReturn24h > 5e-3 && altBasketReturn24h > 5e-3 && altBasketReturn24h > btcReturn24h) {
94
+ return "risk_on";
95
+ }
96
+ if (btcVsAltReturn24h > 5e-3) return "btc_lead";
97
+ if (btcVsAltReturn24h < -5e-3) return "alt_lead";
98
+ return "neutral";
99
+ };
100
+ var normalizeMarketFeatureInterval = (value) => {
101
+ const normalized = String(value || "15m").trim().toLowerCase();
102
+ if (normalized === "1" || normalized === "1m") return "1m";
103
+ if (normalized === "5" || normalized === "5m") return "5m";
104
+ if (normalized === "15" || normalized === "15m") return "15m";
105
+ if (normalized === "60" || normalized === "1h") return "1h";
106
+ return "15m";
107
+ };
108
+ var normalizeBinanceSymbols = (value) => String(value || "").split(",").map((item) => item.trim().toUpperCase()).filter(Boolean);
109
+ var selectBreadthUniverseFromTickers = (tickers, limit) => tickers.filter(
110
+ (ticker) => ticker.symbol.endsWith("USDT") && ticker.symbol !== "BTCUSDT" && !STABLE_QUOTE_SYMBOLS.has(ticker.symbol) && Number.isFinite(ticker.turnover24h) && ticker.turnover24h > 0
111
+ ).sort((a, b) => b.turnover24h - a.turnover24h).slice(0, Math.max(0, limit)).map((ticker) => ticker.symbol);
112
+ var estimateBinanceMarketDataVolume = ({
113
+ symbols,
114
+ days,
115
+ interval,
116
+ includeAggTrades,
117
+ includeBreadth,
118
+ breadthLimit
119
+ }) => {
120
+ const intervalMs = MARKET_FEATURE_INTERVAL_MS[interval];
121
+ const bucketRowsPerSymbol = Math.ceil(days * 864e5 / intervalMs);
122
+ const aggTradeBucketRows = includeAggTrades ? symbols.length * bucketRowsPerSymbol : 0;
123
+ const breadthSymbols = includeBreadth ? Math.max(0, breadthLimit) : 0;
124
+ const breadthCandleRows = breadthSymbols * bucketRowsPerSymbol;
125
+ const breadthRows = includeBreadth ? bucketRowsPerSymbol : 0;
126
+ return {
127
+ interval,
128
+ days,
129
+ symbols: symbols.length,
130
+ bucketRowsPerSymbol,
131
+ aggTradeBucketRows,
132
+ breadthSymbols,
133
+ breadthCandleRows,
134
+ breadthRows,
135
+ estimatedStoredRows: aggTradeBucketRows + breadthRows
136
+ };
137
+ };
138
+ var aggregateAggTradesToRows = ({
139
+ symbol,
140
+ interval,
141
+ trades,
142
+ source = "binance_agg_trades"
143
+ }) => {
144
+ const intervalMs = MARKET_FEATURE_INTERVAL_MS[interval];
145
+ const buckets = /* @__PURE__ */ new Map();
146
+ for (const trade of trades) {
147
+ const bucketTs = Math.floor(trade.timestamp / intervalMs) * intervalMs;
148
+ const row = buckets.get(bucketTs) ?? {
149
+ symbol,
150
+ interval,
151
+ ts: new Date(bucketTs),
152
+ trades: 0,
153
+ buyBaseVolume: 0,
154
+ sellBaseVolume: 0,
155
+ buyQuoteVolume: 0,
156
+ sellQuoteVolume: 0,
157
+ netBaseDelta: 0,
158
+ netQuoteDelta: 0,
159
+ buyPressurePct: null,
160
+ source
161
+ };
162
+ const quote = trade.price * trade.quantity;
163
+ const isAggressiveSell = trade.isBuyerMaker;
164
+ row.trades += 1;
165
+ if (isAggressiveSell) {
166
+ row.sellBaseVolume = (row.sellBaseVolume ?? 0) + trade.quantity;
167
+ row.sellQuoteVolume = (row.sellQuoteVolume ?? 0) + quote;
168
+ } else {
169
+ row.buyBaseVolume = (row.buyBaseVolume ?? 0) + trade.quantity;
170
+ row.buyQuoteVolume = (row.buyQuoteVolume ?? 0) + quote;
171
+ }
172
+ row.netBaseDelta = (row.buyBaseVolume ?? 0) - (row.sellBaseVolume ?? 0);
173
+ row.netQuoteDelta = (row.buyQuoteVolume ?? 0) - (row.sellQuoteVolume ?? 0);
174
+ row.buyPressurePct = safeDivide(
175
+ row.buyBaseVolume ?? 0,
176
+ (row.buyBaseVolume ?? 0) + (row.sellBaseVolume ?? 0)
177
+ );
178
+ buckets.set(bucketTs, row);
179
+ }
180
+ return [...buckets.values()].sort((a, b) => a.ts.getTime() - b.ts.getTime());
181
+ };
182
+ var buildMarketBreadthRows = ({
183
+ universe,
184
+ interval,
185
+ candlesBySymbol,
186
+ btcCandles,
187
+ source = "binance_klines"
188
+ }) => {
189
+ const timestamps = /* @__PURE__ */ new Set();
190
+ const indexedSymbols = Object.values(candlesBySymbol).map((candles) => ({
191
+ candles,
192
+ byTimestamp: new Map(
193
+ candles.map((candle, index) => [candle.timestamp, index])
194
+ ),
195
+ turnoverPrefix: buildPrefixSum(
196
+ candles.map((candle) => Math.max(0, candle.turnover ?? 0))
197
+ ),
198
+ closePrefix: buildPrefixSum(candles.map((candle) => candle.close))
199
+ }));
200
+ const btcIndexed = btcCandles ? {
201
+ candles: btcCandles,
202
+ byTimestamp: new Map(
203
+ btcCandles.map((candle, index) => [candle.timestamp, index])
204
+ ),
205
+ turnoverPrefix: buildPrefixSum(
206
+ btcCandles.map((candle) => Math.max(0, candle.turnover ?? 0))
207
+ )
208
+ } : null;
209
+ const intervalMs = MARKET_FEATURE_INTERVAL_MS[interval];
210
+ const bars1h = Math.max(1, Math.round(36e5 / intervalMs));
211
+ const bars4h = Math.max(1, Math.round(144e5 / intervalMs));
212
+ const bars24h = Math.max(1, Math.round(864e5 / intervalMs));
213
+ for (const candles of Object.values(candlesBySymbol)) {
214
+ for (const candle of candles) timestamps.add(candle.timestamp);
215
+ }
216
+ return [...timestamps].sort((a, b) => a - b).map((timestamp) => {
217
+ const returns = [];
218
+ const weightedReturns = [];
219
+ let advancers = 0;
220
+ let decliners = 0;
221
+ let unchanged = 0;
222
+ let aboveMa20 = 0;
223
+ let aboveMa20Eligible = 0;
224
+ let aboveMa50 = 0;
225
+ let aboveMa50Eligible = 0;
226
+ const altReturns1h = [];
227
+ const altReturns4h = [];
228
+ const altReturns24h = [];
229
+ let altTurnover1h = 0;
230
+ let altTurnover24h = 0;
231
+ let previousAltTurnover24h = 0;
232
+ for (const indexed of indexedSymbols) {
233
+ const { candles, byTimestamp, turnoverPrefix, closePrefix } = indexed;
234
+ const index = byTimestamp.get(timestamp);
235
+ if (index == null) continue;
236
+ const candle = candles[index];
237
+ const previous = candles[index - 1];
238
+ const ret = previous && previous.close > 0 ? (candle.close - previous.close) / previous.close : 0;
239
+ if (ret > 0) advancers += 1;
240
+ else if (ret < 0) decliners += 1;
241
+ else unchanged += 1;
242
+ returns.push(ret);
243
+ weightedReturns.push({
244
+ value: ret,
245
+ weight: Math.max(0, candle.turnover ?? 0)
246
+ });
247
+ const ma20Start = index - 19;
248
+ if (ma20Start >= 0) {
249
+ aboveMa20Eligible += 1;
250
+ const ma20 = sumPrefixRange(closePrefix, ma20Start, index) / 20;
251
+ if (candle.close > ma20) aboveMa20 += 1;
252
+ }
253
+ const ma50Start = index - 49;
254
+ if (ma50Start >= 0) {
255
+ aboveMa50Eligible += 1;
256
+ const ma50 = sumPrefixRange(closePrefix, ma50Start, index) / 50;
257
+ if (candle.close > ma50) aboveMa50 += 1;
258
+ }
259
+ const altReturn1h = windowReturn(candles, index, bars1h);
260
+ const altReturn4h = windowReturn(candles, index, bars4h);
261
+ const altReturn24h = windowReturn(candles, index, bars24h);
262
+ if (altReturn1h != null) altReturns1h.push(altReturn1h);
263
+ if (altReturn4h != null) altReturns4h.push(altReturn4h);
264
+ if (altReturn24h != null) altReturns24h.push(altReturn24h);
265
+ altTurnover1h += sumPrefixRange(
266
+ turnoverPrefix,
267
+ index - bars1h + 1,
268
+ index
269
+ );
270
+ altTurnover24h += sumPrefixRange(
271
+ turnoverPrefix,
272
+ index - bars24h + 1,
273
+ index
274
+ );
275
+ previousAltTurnover24h += sumPrefixRange(
276
+ turnoverPrefix,
277
+ index - bars24h * 2 + 1,
278
+ index - bars24h
279
+ );
280
+ }
281
+ const weightSum = weightedReturns.reduce(
282
+ (sum, item) => sum + item.weight,
283
+ 0
284
+ );
285
+ const volumeWeightedReturn = weightSum > 0 ? weightedReturns.reduce(
286
+ (sum, item) => sum + item.value * item.weight,
287
+ 0
288
+ ) / weightSum : null;
289
+ const btcIndex = btcIndexed?.byTimestamp.get(timestamp);
290
+ const btcReturn1h = btcIndexed && btcIndex != null ? windowReturn(btcIndexed.candles, btcIndex, bars1h) : null;
291
+ const btcReturn4h = btcIndexed && btcIndex != null ? windowReturn(btcIndexed.candles, btcIndex, bars4h) : null;
292
+ const btcReturn24h = btcIndexed && btcIndex != null ? windowReturn(btcIndexed.candles, btcIndex, bars24h) : null;
293
+ const btcTurnover1h = btcIndexed && btcIndex != null ? sumPrefixRange(
294
+ btcIndexed.turnoverPrefix,
295
+ btcIndex - bars1h + 1,
296
+ btcIndex
297
+ ) : null;
298
+ const btcTurnover24h = btcIndexed && btcIndex != null ? sumPrefixRange(
299
+ btcIndexed.turnoverPrefix,
300
+ btcIndex - bars24h + 1,
301
+ btcIndex
302
+ ) : null;
303
+ const previousBtcTurnover24h = btcIndexed && btcIndex != null ? sumPrefixRange(
304
+ btcIndexed.turnoverPrefix,
305
+ btcIndex - bars24h * 2 + 1,
306
+ btcIndex - bars24h
307
+ ) : null;
308
+ const altBasketReturn1h = mean(altReturns1h);
309
+ const altBasketReturn4h = mean(altReturns4h);
310
+ const altBasketReturn24h = mean(altReturns24h);
311
+ const btcVsAltReturn1h = btcReturn1h == null || altBasketReturn1h == null ? null : btcReturn1h - altBasketReturn1h;
312
+ const btcVsAltReturn4h = btcReturn4h == null || altBasketReturn4h == null ? null : btcReturn4h - altBasketReturn4h;
313
+ const btcVsAltReturn24h = btcReturn24h == null || altBasketReturn24h == null ? null : btcReturn24h - altBasketReturn24h;
314
+ const btcTurnoverShare1h = btcTurnover1h == null ? null : safeDivide(btcTurnover1h, btcTurnover1h + altTurnover1h);
315
+ const btcTurnoverShare24h = btcTurnover24h == null ? null : safeDivide(btcTurnover24h, btcTurnover24h + altTurnover24h);
316
+ const previousBtcTurnoverShare24h = previousBtcTurnover24h == null ? null : safeDivide(
317
+ previousBtcTurnover24h,
318
+ previousBtcTurnover24h + previousAltTurnover24h
319
+ );
320
+ const btcTurnoverShareChange24h = btcTurnoverShare24h == null || previousBtcTurnoverShare24h == null ? null : btcTurnoverShare24h - previousBtcTurnoverShare24h;
321
+ return {
322
+ universe,
323
+ interval,
324
+ ts: new Date(timestamp),
325
+ symbolsCount: returns.length,
326
+ advancers,
327
+ decliners,
328
+ unchanged,
329
+ advanceDeclineRatio: safeDivide(advancers, decliners || 1),
330
+ pctAboveMa20: safeDivide(aboveMa20, aboveMa20Eligible),
331
+ pctAboveMa50: safeDivide(aboveMa50, aboveMa50Eligible),
332
+ equalWeightedReturn: mean(returns),
333
+ volumeWeightedReturn,
334
+ dispersion: standardDeviation(returns),
335
+ btcReturn1h,
336
+ btcReturn4h,
337
+ btcReturn24h,
338
+ altBasketReturn1h,
339
+ altBasketReturn4h,
340
+ altBasketReturn24h,
341
+ btcVsAltReturn1h,
342
+ btcVsAltReturn4h,
343
+ btcVsAltReturn24h,
344
+ btcTurnoverShare1h,
345
+ btcTurnoverShare24h,
346
+ btcTurnoverShareChange24h,
347
+ altVolToBtcVol24h: btcTurnover24h == null ? null : safeDivide(altTurnover24h, btcTurnover24h),
348
+ altDispersion24h: standardDeviation(altReturns24h),
349
+ btcAltRegime: classifyBtcAltRegime({
350
+ btcReturn24h,
351
+ altBasketReturn24h,
352
+ btcVsAltReturn24h
353
+ }),
354
+ source
355
+ };
356
+ }).filter((row) => row.symbolsCount > 0);
357
+ };
358
+
359
+ // src/scripts/binanceMarketIngest.ts
360
+ import_args.default.example(
361
+ "yarn cli:node8g binance:market-ingest --all --symbols BTCUSDT,ETHUSDT --days 0.05 --interval 1m --write",
362
+ "Ingest Binance public market breadth and historical aggTrades buckets"
363
+ );
364
+ import_args.default.option(
365
+ ["s", "symbols"],
366
+ "Comma-separated target symbols",
367
+ "BTCUSDT,ETHUSDT"
368
+ );
369
+ import_args.default.option(["i", "interval"], "Aggregation interval: 1m,5m,15m,1h", "1m");
370
+ import_args.default.option(["d", "days"], "Lookback window in days", "1");
371
+ import_args.default.option(["h", "hours"], "Lookback window in hours; overrides --days");
372
+ import_args.default.option(["a", "aggTrades"], "Fetch and bucket Binance aggTrades");
373
+ import_args.default.option(
374
+ ["b", "breadth"],
375
+ "Build alt-basket market breadth from Binance klines"
376
+ );
377
+ import_args.default.option(["A", "all"], "Enable aggTrades and breadth");
378
+ import_args.default.option(
379
+ ["w", "write"],
380
+ "Write rows to Timescale; without this flag only estimate"
381
+ );
382
+ import_args.default.option(
383
+ ["B", "breadthLimit"],
384
+ "Top USDT symbols used for breadth universe",
385
+ 30
386
+ );
387
+ import_args.default.option(
388
+ ["M", "batchMinutes"],
389
+ "aggTrades request window size in minutes",
390
+ 15
391
+ );
392
+ import_args.default.option(
393
+ ["r", "requestDelayMs"],
394
+ "Delay between Binance aggTrades requests",
395
+ 75
396
+ );
397
+ var flags = import_args.default.parse(process.argv);
398
+ var asFloat = (value, fallback) => {
399
+ const parsed = Number.parseFloat(String(value ?? ""));
400
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
401
+ };
402
+ var asInt = (value, fallback) => {
403
+ const parsed = Number.parseInt(String(value ?? ""), 10);
404
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
405
+ };
406
+ var sleep = (ms) => ms > 0 ? new Promise((resolve) => setTimeout(resolve, ms)) : Promise.resolve();
407
+ var intervalToConnectorInterval = (interval) => {
408
+ if (interval === "1m") return "1";
409
+ if (interval === "5m") return "5";
410
+ if (interval === "15m") return "15";
411
+ return "60";
412
+ };
413
+ var fetchAggTradesForWindow = async ({
414
+ connector,
415
+ symbol,
416
+ fromMs,
417
+ toMs,
418
+ batchMinutes,
419
+ requestDelayMs
420
+ }) => {
421
+ if (!connector.getAggTrades) return [];
422
+ const rows = [];
423
+ const batchMs = Math.max(1, batchMinutes) * 6e4;
424
+ let cursor = fromMs;
425
+ while (cursor <= toMs) {
426
+ const endTime = Math.min(toMs, cursor + batchMs - 1);
427
+ let pageCursor = cursor;
428
+ while (pageCursor <= endTime) {
429
+ const page = await connector.getAggTrades({
430
+ symbol,
431
+ startTime: pageCursor,
432
+ endTime,
433
+ limit: 1e3
434
+ });
435
+ if (!page.length) break;
436
+ rows.push(...page);
437
+ const lastTs = page[page.length - 1]?.timestamp;
438
+ if (page.length < 1e3 || !Number.isFinite(lastTs)) break;
439
+ const nextCursor = Math.max(pageCursor + 1, Number(lastTs) + 1);
440
+ if (nextCursor > endTime) break;
441
+ pageCursor = nextCursor;
442
+ await sleep(requestDelayMs);
443
+ }
444
+ cursor = endTime + 1;
445
+ await sleep(requestDelayMs);
446
+ }
447
+ return rows;
448
+ };
449
+ var printEstimate = (estimate) => {
450
+ console.log(import_chalk.default.cyan("Binance market ingest estimate"));
451
+ console.log(`interval: ${estimate.interval}`);
452
+ console.log(`days: ${estimate.days}`);
453
+ console.log(`target symbols: ${estimate.symbols}`);
454
+ console.log(`bucket rows/symbol: ${estimate.bucketRowsPerSymbol}`);
455
+ console.log(`aggTrades bucket rows: ${estimate.aggTradeBucketRows}`);
456
+ console.log(`breadth symbols: ${estimate.breadthSymbols}`);
457
+ console.log(`breadth candle reads: ${estimate.breadthCandleRows}`);
458
+ console.log(`breadth rows: ${estimate.breadthRows}`);
459
+ console.log(`estimated stored rows: ${estimate.estimatedStoredRows}`);
460
+ };
461
+ var main = async () => {
462
+ const symbols = normalizeBinanceSymbols(flags.symbols);
463
+ const interval = normalizeMarketFeatureInterval(flags.interval);
464
+ const hours = flags.hours == null ? null : asFloat(flags.hours, 0);
465
+ const days = hours != null && hours > 0 ? hours / 24 : asFloat(flags.days, 1);
466
+ const breadthLimit = asInt(flags.breadthLimit, 30);
467
+ const batchMinutes = asInt(flags.batchMinutes, 15);
468
+ const requestDelayMs = asInt(flags.requestDelayMs, 75);
469
+ const includeAll = Boolean(flags.all);
470
+ const includeAggTrades = includeAll || Boolean(flags.aggTrades);
471
+ const includeBreadth = includeAll || Boolean(flags.breadth);
472
+ const anyMode = includeAggTrades || includeBreadth;
473
+ const modes = {
474
+ includeAggTrades: anyMode ? includeAggTrades : true,
475
+ includeBreadth: anyMode ? includeBreadth : true
476
+ };
477
+ if (!symbols.length) throw new Error("No symbols provided");
478
+ const estimate = estimateBinanceMarketDataVolume({
479
+ symbols,
480
+ days,
481
+ interval,
482
+ includeAggTrades: modes.includeAggTrades,
483
+ includeBreadth: modes.includeBreadth,
484
+ breadthLimit
485
+ });
486
+ printEstimate(estimate);
487
+ if (!flags.write) {
488
+ console.log(import_chalk.default.yellow("Dry run only. Pass --write to ingest."));
489
+ return;
490
+ }
491
+ await (0, import_timescale.waitForDbReady)();
492
+ const connector = await import_connectors.connectors[import_connectors.ConnectorNames.Binance]({
493
+ userName: "root"
494
+ });
495
+ const toMs = Math.floor(Date.now() / MARKET_FEATURE_INTERVAL_MS[interval]) * MARKET_FEATURE_INTERVAL_MS[interval];
496
+ const fromMs = toMs - days * 864e5;
497
+ let aggTradesRaw = 0;
498
+ let tradeFlowRows = 0;
499
+ let breadthRows = 0;
500
+ let breadthCandleRows = 0;
501
+ if (modes.includeAggTrades) {
502
+ for (const symbol of symbols) {
503
+ process.stdout.write(import_chalk.default.cyan(`aggTrades ${symbol}... `));
504
+ const trades = await fetchAggTradesForWindow({
505
+ connector,
506
+ symbol,
507
+ fromMs,
508
+ toMs,
509
+ batchMinutes,
510
+ requestDelayMs
511
+ });
512
+ const rows = aggregateAggTradesToRows({ symbol, interval, trades });
513
+ await (0, import_timescale.upsertMarketTradeFlowRows)(rows);
514
+ aggTradesRaw += trades.length;
515
+ tradeFlowRows += rows.length;
516
+ process.stdout.write(
517
+ `${trades.length} trades -> ${rows.length} buckets
518
+ `
519
+ );
520
+ }
521
+ }
522
+ if (modes.includeBreadth) {
523
+ const tickers = await connector.getTickers();
524
+ const breadthSymbols = selectBreadthUniverseFromTickers(
525
+ tickers,
526
+ breadthLimit
527
+ );
528
+ const connectorInterval = intervalToConnectorInterval(interval);
529
+ const candlesBySymbol = {};
530
+ for (const symbol of breadthSymbols) {
531
+ process.stdout.write(import_chalk.default.cyan(`breadth candles ${symbol}... `));
532
+ const candles = await connector.kline({
533
+ symbol,
534
+ interval: connectorInterval,
535
+ start: fromMs,
536
+ end: toMs,
537
+ silent: true
538
+ });
539
+ candlesBySymbol[symbol] = candles;
540
+ breadthCandleRows += candles.length;
541
+ process.stdout.write(`${candles.length}
542
+ `);
543
+ }
544
+ const universe = `binance_top${breadthSymbols.length}_usdt`;
545
+ const rows = buildMarketBreadthRows({
546
+ universe,
547
+ interval,
548
+ candlesBySymbol
549
+ });
550
+ await (0, import_timescale.upsertMarketBreadthRows)(rows);
551
+ breadthRows += rows.length;
552
+ }
553
+ console.log(import_chalk.default.green("Binance market ingest done"));
554
+ console.log(`aggTrades raw rows: ${aggTradesRaw}`);
555
+ console.log(`trade-flow bucket rows: ${tradeFlowRows}`);
556
+ console.log(`breadth candle rows read: ${breadthCandleRows}`);
557
+ console.log(`breadth rows: ${breadthRows}`);
558
+ console.log(
559
+ `stored rows: ${tradeFlowRows + breadthRows} (raw aggTrades are not stored)`
560
+ );
561
+ };
562
+ // Annotate the CommonJS export names for ESM import in node:
563
+ 0 && (module.exports = {
564
+ main
565
+ });
@@ -5,6 +5,10 @@ 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 __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
8
12
  var __copyProps = (to, from, except, desc) => {
9
13
  if (from && typeof from === "object" || typeof from === "function") {
10
14
  for (let key of __getOwnPropNames(from))
@@ -21,8 +25,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
25
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
26
  mod
23
27
  ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
24
29
 
25
30
  // src/scripts/bot.ts
31
+ var bot_exports = {};
32
+ __export(bot_exports, {
33
+ main: () => main
34
+ });
35
+ module.exports = __toCommonJS(bot_exports);
26
36
  var import_config = require("dotenv/config");
27
37
 
28
38
  // src/lib/runBot.ts
@@ -128,6 +138,7 @@ var runBot = async () => {
128
138
  const btcCandle = btcData.pop();
129
139
  const strategy = await strategyCreator({
130
140
  userName,
141
+ connectorName,
131
142
  config: strategyConfig,
132
143
  symbol,
133
144
  data,
@@ -155,8 +166,11 @@ var runBot = async () => {
155
166
  };
156
167
 
157
168
  // src/scripts/bot.ts
158
- var run = async () => {
169
+ var main = async () => {
159
170
  await runBot();
160
171
  process.exit();
161
172
  };
162
- run();
173
+ // Annotate the CommonJS export names for ESM import in node:
174
+ 0 && (module.exports = {
175
+ main
176
+ });
@@ -8,6 +8,10 @@ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
8
  var __commonJS = (cb, mod) => function __require() {
9
9
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
10
  };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
11
15
  var __copyProps = (to, from, except, desc) => {
12
16
  if (from && typeof from === "object" || typeof from === "function") {
13
17
  for (let key of __getOwnPropNames(from))
@@ -24,6 +28,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
28
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
29
  mod
26
30
  ));
31
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
32
 
28
33
  // ../../node_modules/postgres-array/index.js
29
34
  var require_postgres_array = __commonJS({
@@ -4957,6 +4962,11 @@ var require_lib2 = __commonJS({
4957
4962
  });
4958
4963
 
4959
4964
  // src/scripts/candlesMigrateProvider.ts
4965
+ var candlesMigrateProvider_exports = {};
4966
+ __export(candlesMigrateProvider_exports, {
4967
+ main: () => main
4968
+ });
4969
+ module.exports = __toCommonJS(candlesMigrateProvider_exports);
4960
4970
  var import_args = __toESM(require("args"));
4961
4971
  var import_chalk = __toESM(require("chalk"));
4962
4972
 
@@ -5276,27 +5286,27 @@ var printProgress = (message) => {
5276
5286
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().slice(11, 19);
5277
5287
  console.log(import_chalk.default.gray(`[${timestamp}] ${message}`));
5278
5288
  };
5279
- var run = async () => {
5280
- printProgress(
5281
- `Start candles provider migration for ${String(flags.schema || "public")}.${String(
5282
- flags.table || "candles"
5283
- )}${flags["dry-run"] ? " (dry-run)" : ""}`
5284
- );
5285
- const summary = await runCandlesProviderMigration(pool, {
5286
- schema: String(flags.schema || "public"),
5287
- table: String(flags.table || "candles"),
5288
- dryRun: Boolean(flags["dry-run"]),
5289
- recompress: !Boolean(flags["skip-recompress"]),
5290
- keepPolicyPaused: Boolean(flags["keep-policy-paused"]),
5291
- onProgress: printProgress
5292
- });
5293
- printSummary(summary);
5289
+ var main = async () => {
5290
+ try {
5291
+ printProgress(
5292
+ `Start candles provider migration for ${String(flags.schema || "public")}.${String(
5293
+ flags.table || "candles"
5294
+ )}${flags["dry-run"] ? " (dry-run)" : ""}`
5295
+ );
5296
+ const summary = await runCandlesProviderMigration(pool, {
5297
+ schema: String(flags.schema || "public"),
5298
+ table: String(flags.table || "candles"),
5299
+ dryRun: Boolean(flags["dry-run"]),
5300
+ recompress: !Boolean(flags["skip-recompress"]),
5301
+ keepPolicyPaused: Boolean(flags["keep-policy-paused"]),
5302
+ onProgress: printProgress
5303
+ });
5304
+ printSummary(summary);
5305
+ } finally {
5306
+ await pool.end().catch(() => void 0);
5307
+ }
5294
5308
  };
5295
- run().catch((error) => {
5296
- console.error(
5297
- import_chalk.default.red(`candles:migrate-provider failed: ${String(error)}`)
5298
- );
5299
- process.exitCode = 1;
5300
- }).finally(async () => {
5301
- await pool.end().catch(() => void 0);
5309
+ // Annotate the CommonJS export names for ESM import in node:
5310
+ 0 && (module.exports = {
5311
+ main
5302
5312
  });