@tradejs/cli 2.0.0 → 2.0.2
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 +384 -122
- package/dist/lib/aiTrainCharts.js +49 -2
- package/dist/lib/aiTrainMetrics.js +49 -2
- package/dist/lib/aiTrainResearch.js +58 -4
- package/dist/lib/derivativesContextBackfill.js +262 -107
- package/dist/lib/marketContextPrepare.js +256 -107
- package/dist/scripts/aiPocketSearch.js +49 -2
- package/dist/scripts/aiTrain.js +76 -4
- package/dist/scripts/backtest.js +256 -107
- package/dist/scripts/derivativesIngest.js +11 -4
- package/dist/scripts/derivativesIngestCoinalyzeAll.js +38 -4
- package/dist/scripts/replay.js +256 -107
- package/dist/scripts/replayRunner.js +256 -107
- package/dist/scripts/runtimeParity.js +256 -107
- package/dist/scripts/signals.js +256 -107
- package/dist/scripts/signalsDaemon.js +256 -107
- package/package.json +9 -9
package/dist/scripts/signals.js
CHANGED
|
@@ -2610,7 +2610,7 @@ var import_userSettings = require("@tradejs/infra/userSettings");
|
|
|
2610
2610
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
2611
2611
|
var DAY_MS2 = 24 * HOUR_MS;
|
|
2612
2612
|
var DEFAULT_LOOKBACK_HOURS = 48;
|
|
2613
|
-
var
|
|
2613
|
+
var SOURCE_INTERVALS = ["15m"];
|
|
2614
2614
|
var coinalyzeIntervalMap = {
|
|
2615
2615
|
"15m": "15min",
|
|
2616
2616
|
"1h": "1hour"
|
|
@@ -2671,10 +2671,7 @@ var isDerivativesContextBackfillEnabled = (env) => {
|
|
|
2671
2671
|
var shouldBackfillDerivativesContextForBacktest = (params) => !params.cacheOnly && (params.aiEnabled || params.mlEnabled) && isBacktestDerivativesContextEnabled();
|
|
2672
2672
|
var shouldBackfillDerivativesContextForSignals = (params) => !params.cacheOnly && isSignalsDerivativesContextEnabled();
|
|
2673
2673
|
var resolveDerivativesContextIntervals = () => {
|
|
2674
|
-
|
|
2675
|
-
process.env.DERIVATIVES_CONTEXT_INTERVALS
|
|
2676
|
-
);
|
|
2677
|
-
return intervals.length ? intervals : DEFAULT_INTERVALS;
|
|
2674
|
+
return [...SOURCE_INTERVALS];
|
|
2678
2675
|
};
|
|
2679
2676
|
var resolveDerivativesContextLookbackMs = () => {
|
|
2680
2677
|
const hours = Number(process.env.DERIVATIVES_CONTEXT_LOOKBACK_HOURS);
|
|
@@ -2709,9 +2706,10 @@ var resolveDerivativesContextBackfillWindow = (params) => {
|
|
|
2709
2706
|
};
|
|
2710
2707
|
var resolveDerivativesContextIntervalBackfillWindow = (params) => {
|
|
2711
2708
|
const intervalMs2 = derivativesIntervalMs(params.interval);
|
|
2709
|
+
const alignedToMs = params.closedOnly ? (0, import_indicators2.getLastClosedDerivativesBarStartMs)(params.toMs, params.interval) : Math.floor(params.toMs / intervalMs2) * intervalMs2;
|
|
2712
2710
|
return {
|
|
2713
2711
|
fromMs: Math.floor(params.fromMs / intervalMs2) * intervalMs2,
|
|
2714
|
-
toMs:
|
|
2712
|
+
toMs: alignedToMs,
|
|
2715
2713
|
intervalMs: intervalMs2
|
|
2716
2714
|
};
|
|
2717
2715
|
};
|
|
@@ -2729,6 +2727,39 @@ var resolveDerivativesContextMissingFetchFromMs = (params) => {
|
|
|
2729
2727
|
}
|
|
2730
2728
|
return null;
|
|
2731
2729
|
};
|
|
2730
|
+
var resolveDerivativesContextFetchFromMs = (params) => resolveDerivativesContextMissingFetchFromMs(params) ?? (params.refreshClosedTail ? params.toMs : null);
|
|
2731
|
+
var resolveDerivativesContextRequiredFetchFromMs = (params) => {
|
|
2732
|
+
const dataCoverageFromMs = params.dataCoverageKeyExists ? null : params.mode === "signals" ? params.fromMs : resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
2733
|
+
ranges: params.dataCoverageRanges,
|
|
2734
|
+
fromMs: params.fromMs,
|
|
2735
|
+
toMs: params.toMs,
|
|
2736
|
+
intervalMs: params.intervalMs
|
|
2737
|
+
});
|
|
2738
|
+
const edgesFromMs = dataCoverageFromMs == null ? null : resolveDerivativesContextFetchFromMs({
|
|
2739
|
+
edges: params.edges,
|
|
2740
|
+
fromMs: params.fromMs,
|
|
2741
|
+
toMs: params.toMs,
|
|
2742
|
+
intervalMs: params.intervalMs,
|
|
2743
|
+
refreshClosedTail: params.mode === "signals"
|
|
2744
|
+
});
|
|
2745
|
+
const dataFetchFromMs = dataCoverageFromMs != null && edgesFromMs != null ? Math.max(dataCoverageFromMs, edgesFromMs) : null;
|
|
2746
|
+
const confirmedLiquidationWindow = (0, import_indicators2.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
2747
|
+
interval: params.interval,
|
|
2748
|
+
fromMs: params.fromMs,
|
|
2749
|
+
toMs: params.toMs,
|
|
2750
|
+
nowMs: params.nowMs
|
|
2751
|
+
});
|
|
2752
|
+
const liquidationFetchFromMs = confirmedLiquidationWindow ? resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
2753
|
+
ranges: params.liquidationCoverageRanges,
|
|
2754
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
2755
|
+
toMs: confirmedLiquidationWindow.toMs,
|
|
2756
|
+
intervalMs: params.intervalMs
|
|
2757
|
+
}) : null;
|
|
2758
|
+
const fetchStarts = [dataFetchFromMs, liquidationFetchFromMs].filter(
|
|
2759
|
+
(value) => value != null
|
|
2760
|
+
);
|
|
2761
|
+
return fetchStarts.length ? Math.min(...fetchStarts) : null;
|
|
2762
|
+
};
|
|
2732
2763
|
var countBackfillWindows = (params) => {
|
|
2733
2764
|
let count = 0;
|
|
2734
2765
|
let cursor = params.fromMs;
|
|
@@ -2792,6 +2823,14 @@ var groupDerivativesContextMissingFetchRanges = (ranges) => {
|
|
|
2792
2823
|
}
|
|
2793
2824
|
return [...groups.entries()].sort(([a], [b]) => a - b).map(([fromMs, items]) => ({ fromMs, items }));
|
|
2794
2825
|
};
|
|
2826
|
+
var getMissingClosedDerivativesSymbols = (params) => {
|
|
2827
|
+
const availableSymbols = new Set(
|
|
2828
|
+
params.rows.filter((row) => row.ts.getTime() === params.expectedTimestamp).map((row) => row.symbol.trim().toUpperCase())
|
|
2829
|
+
);
|
|
2830
|
+
return params.symbols.filter(
|
|
2831
|
+
(symbol) => !availableSymbols.has(symbol.trim().toUpperCase())
|
|
2832
|
+
);
|
|
2833
|
+
};
|
|
2795
2834
|
var coverageKey = (params) => [
|
|
2796
2835
|
params.symbol.trim().toUpperCase(),
|
|
2797
2836
|
params.interval,
|
|
@@ -3056,7 +3095,8 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3056
3095
|
mode,
|
|
3057
3096
|
startMs,
|
|
3058
3097
|
endMs,
|
|
3059
|
-
preloadStartMs: params.preloadStartMs
|
|
3098
|
+
preloadStartMs: params.preloadStartMs,
|
|
3099
|
+
nowMs: Date.now()
|
|
3060
3100
|
});
|
|
3061
3101
|
if (safeEndMs <= fromMs) {
|
|
3062
3102
|
return skippedBackfillResult2();
|
|
@@ -3071,7 +3111,8 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3071
3111
|
...resolveDerivativesContextIntervalBackfillWindow({
|
|
3072
3112
|
fromMs,
|
|
3073
3113
|
toMs: safeEndMs,
|
|
3074
|
-
interval: interval2
|
|
3114
|
+
interval: interval2,
|
|
3115
|
+
closedOnly: mode === "signals"
|
|
3075
3116
|
})
|
|
3076
3117
|
})).filter((item) => item.toMs > item.fromMs);
|
|
3077
3118
|
if (!intervalWindows.length) {
|
|
@@ -3089,15 +3130,33 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3089
3130
|
);
|
|
3090
3131
|
const coverageKeysByInterval = /* @__PURE__ */ new Map();
|
|
3091
3132
|
const coverageRangesByInterval = /* @__PURE__ */ new Map();
|
|
3133
|
+
const liquidationCoverageRangesByInterval = /* @__PURE__ */ new Map();
|
|
3134
|
+
const coverageNowMs = Date.now();
|
|
3092
3135
|
await Promise.all(
|
|
3093
3136
|
intervalWindows.map(async (window2) => {
|
|
3094
|
-
const
|
|
3095
|
-
source: "coinalyze",
|
|
3096
|
-
symbols,
|
|
3137
|
+
const confirmedLiquidationWindow = (0, import_indicators2.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3097
3138
|
interval: window2.interval,
|
|
3098
3139
|
fromMs: window2.fromMs,
|
|
3099
|
-
toMs: window2.toMs
|
|
3140
|
+
toMs: window2.toMs,
|
|
3141
|
+
nowMs: coverageNowMs
|
|
3100
3142
|
});
|
|
3143
|
+
const [coverageRows, liquidationCoverageRows] = await Promise.all([
|
|
3144
|
+
(0, import_timescale2.getDerivativesBackfillCoverage)({
|
|
3145
|
+
source: "coinalyze",
|
|
3146
|
+
symbols,
|
|
3147
|
+
interval: window2.interval,
|
|
3148
|
+
fromMs: window2.fromMs,
|
|
3149
|
+
toMs: window2.toMs
|
|
3150
|
+
}),
|
|
3151
|
+
confirmedLiquidationWindow ? (0, import_timescale2.getDerivativesMetricCoverage)({
|
|
3152
|
+
source: "coinalyze",
|
|
3153
|
+
metric: "liquidation",
|
|
3154
|
+
symbols,
|
|
3155
|
+
interval: window2.interval,
|
|
3156
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3157
|
+
toMs: confirmedLiquidationWindow.toMs
|
|
3158
|
+
}) : Promise.resolve([])
|
|
3159
|
+
]);
|
|
3101
3160
|
coverageKeysByInterval.set(
|
|
3102
3161
|
window2.interval,
|
|
3103
3162
|
new Set(
|
|
@@ -3119,6 +3178,17 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3119
3178
|
rangesBySymbol.set(symbol, ranges);
|
|
3120
3179
|
}
|
|
3121
3180
|
coverageRangesByInterval.set(window2.interval, rangesBySymbol);
|
|
3181
|
+
const liquidationRangesBySymbol = /* @__PURE__ */ new Map();
|
|
3182
|
+
for (const row of liquidationCoverageRows) {
|
|
3183
|
+
const symbol = row.symbol.toUpperCase();
|
|
3184
|
+
const ranges = liquidationRangesBySymbol.get(symbol) ?? [];
|
|
3185
|
+
ranges.push({ fromMs: row.fromMs, toMs: row.toMs });
|
|
3186
|
+
liquidationRangesBySymbol.set(symbol, ranges);
|
|
3187
|
+
}
|
|
3188
|
+
liquidationCoverageRangesByInterval.set(
|
|
3189
|
+
window2.interval,
|
|
3190
|
+
liquidationRangesBySymbol
|
|
3191
|
+
);
|
|
3122
3192
|
})
|
|
3123
3193
|
);
|
|
3124
3194
|
const cachedWindows = intervalWindows.reduce(
|
|
@@ -3130,7 +3200,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3130
3200
|
}),
|
|
3131
3201
|
0
|
|
3132
3202
|
);
|
|
3133
|
-
const allBackfillWindowsCached = intervalWindows.every((window2) => {
|
|
3203
|
+
const allBackfillWindowsCached = mode !== "signals" && intervalWindows.every((window2) => {
|
|
3134
3204
|
const edgesBySymbol = edgesByInterval.get(window2.interval);
|
|
3135
3205
|
const coverageKeys = coverageKeysByInterval.get(window2.interval);
|
|
3136
3206
|
const backfillWindows = buildBackfillWindows({
|
|
@@ -3143,7 +3213,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3143
3213
|
(symbol) => backfillWindows.every((backfillWindow) => {
|
|
3144
3214
|
const normalizedSymbol = symbol.toUpperCase();
|
|
3145
3215
|
const coverageRanges = coverageRangesByInterval.get(window2.interval)?.get(normalizedSymbol) ?? [];
|
|
3146
|
-
|
|
3216
|
+
const dataCovered = hasDerivativesWindowCoverage({
|
|
3147
3217
|
edges: edgesBySymbol?.get(normalizedSymbol),
|
|
3148
3218
|
fromMs: backfillWindow.fromMs,
|
|
3149
3219
|
toMs: backfillWindow.toMs
|
|
@@ -3160,6 +3230,19 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3160
3230
|
toMs: backfillWindow.toMs
|
|
3161
3231
|
})
|
|
3162
3232
|
);
|
|
3233
|
+
const confirmedLiquidationWindow = (0, import_indicators2.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3234
|
+
interval: window2.interval,
|
|
3235
|
+
fromMs: backfillWindow.fromMs,
|
|
3236
|
+
toMs: backfillWindow.toMs,
|
|
3237
|
+
nowMs: coverageNowMs
|
|
3238
|
+
});
|
|
3239
|
+
const liquidationCovered = confirmedLiquidationWindow == null || resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
3240
|
+
ranges: liquidationCoverageRangesByInterval.get(window2.interval)?.get(normalizedSymbol) ?? [],
|
|
3241
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3242
|
+
toMs: confirmedLiquidationWindow.toMs,
|
|
3243
|
+
intervalMs: window2.intervalMs
|
|
3244
|
+
}) == null;
|
|
3245
|
+
return dataCovered && liquidationCovered;
|
|
3163
3246
|
})
|
|
3164
3247
|
);
|
|
3165
3248
|
});
|
|
@@ -3244,6 +3327,11 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3244
3327
|
coverageKeysByInterval.set(interval2, coverageKeys);
|
|
3245
3328
|
const coverageRangesBySymbol = coverageRangesByInterval.get(interval2) ?? /* @__PURE__ */ new Map();
|
|
3246
3329
|
coverageRangesByInterval.set(interval2, coverageRangesBySymbol);
|
|
3330
|
+
const liquidationCoverageRangesBySymbol = liquidationCoverageRangesByInterval.get(interval2) ?? /* @__PURE__ */ new Map();
|
|
3331
|
+
liquidationCoverageRangesByInterval.set(
|
|
3332
|
+
interval2,
|
|
3333
|
+
liquidationCoverageRangesBySymbol
|
|
3334
|
+
);
|
|
3247
3335
|
for (let batchIdx = 0; batchIdx < symbolBatches.length; batchIdx += 1) {
|
|
3248
3336
|
const batch = symbolBatches[batchIdx];
|
|
3249
3337
|
let cursor = window2.fromMs;
|
|
@@ -3256,30 +3344,26 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3256
3344
|
fromMs: cursor,
|
|
3257
3345
|
toMs
|
|
3258
3346
|
});
|
|
3259
|
-
if (coverageKeys.has(key)) {
|
|
3260
|
-
return null;
|
|
3261
|
-
}
|
|
3262
3347
|
const normalizedSymbol = item.symbol.toUpperCase();
|
|
3263
|
-
const
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
}
|
|
3282
|
-
return { item, fromMs: Math.max(coverageFromMs, edgesFromMs) };
|
|
3348
|
+
const requiredFromMs = resolveDerivativesContextRequiredFetchFromMs(
|
|
3349
|
+
{
|
|
3350
|
+
mode,
|
|
3351
|
+
interval: interval2,
|
|
3352
|
+
intervalMs: intervalMs2,
|
|
3353
|
+
fromMs: cursor,
|
|
3354
|
+
toMs,
|
|
3355
|
+
nowMs: coverageNowMs,
|
|
3356
|
+
dataCoverageKeyExists: coverageKeys.has(key),
|
|
3357
|
+
dataCoverageRanges: coverageRangesBySymbol.get(normalizedSymbol),
|
|
3358
|
+
liquidationCoverageRanges: liquidationCoverageRangesBySymbol.get(normalizedSymbol),
|
|
3359
|
+
edges: edgesBySymbol.get(normalizedSymbol)
|
|
3360
|
+
}
|
|
3361
|
+
);
|
|
3362
|
+
if (requiredFromMs == null) return null;
|
|
3363
|
+
return {
|
|
3364
|
+
item,
|
|
3365
|
+
fromMs: requiredFromMs
|
|
3366
|
+
};
|
|
3283
3367
|
}).filter(
|
|
3284
3368
|
(item) => item != null
|
|
3285
3369
|
);
|
|
@@ -3293,85 +3377,150 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3293
3377
|
const marketSymbols = missingBatch.map(
|
|
3294
3378
|
(item) => item.marketSymbol
|
|
3295
3379
|
);
|
|
3296
|
-
const
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
metric: "liq",
|
|
3317
|
-
marketSymbols,
|
|
3318
|
-
apiKey,
|
|
3319
|
-
interval: interval2,
|
|
3320
|
-
fromMs: group.fromMs,
|
|
3321
|
-
toMs
|
|
3322
|
-
});
|
|
3323
|
-
const rows = missingBatch.flatMap((item) => {
|
|
3324
|
-
const marketSymbol = item.marketSymbol.toUpperCase();
|
|
3325
|
-
const points = (0, import_indicators2.mergeCoinalyzeMetrics)({
|
|
3326
|
-
symbol: item.symbol,
|
|
3327
|
-
oiRaw: oiMap.get(marketSymbol) ?? [],
|
|
3328
|
-
fundingRaw: fundingMap.get(marketSymbol) ?? [],
|
|
3329
|
-
liqRaw: liqMap.get(marketSymbol) ?? []
|
|
3380
|
+
const maxClosedBarAttempts = mode === "signals" ? asInt2(
|
|
3381
|
+
process.env.DERIVATIVES_CONTEXT_CLOSED_BAR_MAX_ATTEMPTS,
|
|
3382
|
+
3
|
|
3383
|
+
) : 1;
|
|
3384
|
+
const closedBarRetryDelayMs = asInt2(
|
|
3385
|
+
process.env.DERIVATIVES_CONTEXT_CLOSED_BAR_RETRY_DELAY_MS,
|
|
3386
|
+
2e3
|
|
3387
|
+
);
|
|
3388
|
+
let rows = [];
|
|
3389
|
+
let missingClosedSymbols = [];
|
|
3390
|
+
let liquidationRowsByMarket = /* @__PURE__ */ new Map();
|
|
3391
|
+
for (let attempt = 1; attempt <= maxClosedBarAttempts; attempt += 1) {
|
|
3392
|
+
const oiMap = await fetchMetricBatch({
|
|
3393
|
+
endpoint: oiPath,
|
|
3394
|
+
metric: "oi",
|
|
3395
|
+
marketSymbols,
|
|
3396
|
+
apiKey,
|
|
3397
|
+
interval: interval2,
|
|
3398
|
+
fromMs: group.fromMs,
|
|
3399
|
+
toMs
|
|
3330
3400
|
});
|
|
3331
|
-
|
|
3332
|
-
|
|
3401
|
+
const fundingMap = await fetchMetricBatch({
|
|
3402
|
+
endpoint: fundingPath,
|
|
3403
|
+
metric: "funding",
|
|
3404
|
+
marketSymbols,
|
|
3405
|
+
apiKey,
|
|
3406
|
+
interval: interval2,
|
|
3407
|
+
fromMs: group.fromMs,
|
|
3408
|
+
toMs
|
|
3409
|
+
});
|
|
3410
|
+
liquidationRowsByMarket = await fetchMetricBatch({
|
|
3411
|
+
endpoint: liqPath,
|
|
3412
|
+
metric: "liq",
|
|
3413
|
+
marketSymbols,
|
|
3414
|
+
apiKey,
|
|
3415
|
+
interval: interval2,
|
|
3416
|
+
fromMs: group.fromMs,
|
|
3417
|
+
toMs
|
|
3418
|
+
});
|
|
3419
|
+
rows = missingBatch.flatMap((item) => {
|
|
3420
|
+
const marketSymbol = item.marketSymbol.toUpperCase();
|
|
3421
|
+
const points = (0, import_indicators2.mergeCoinalyzeMetrics)({
|
|
3422
|
+
symbol: item.symbol,
|
|
3423
|
+
oiRaw: oiMap.get(marketSymbol) ?? [],
|
|
3424
|
+
fundingRaw: fundingMap.get(marketSymbol) ?? [],
|
|
3425
|
+
liqRaw: liquidationRowsByMarket.get(marketSymbol) ?? []
|
|
3426
|
+
});
|
|
3427
|
+
return (0, import_indicators2.coinalyzePointsToRows)(points, interval2, "coinalyze");
|
|
3428
|
+
});
|
|
3429
|
+
missingClosedSymbols = mode === "signals" ? getMissingClosedDerivativesSymbols({
|
|
3430
|
+
symbols: missingBatch.map((item) => item.symbol),
|
|
3431
|
+
rows,
|
|
3432
|
+
expectedTimestamp: toMs
|
|
3433
|
+
}) : [];
|
|
3434
|
+
if (!missingClosedSymbols.length) break;
|
|
3435
|
+
if (attempt < maxClosedBarAttempts) {
|
|
3436
|
+
await (0, import_async.delay)(closedBarRetryDelayMs);
|
|
3437
|
+
}
|
|
3438
|
+
}
|
|
3439
|
+
if (missingClosedSymbols.length) {
|
|
3440
|
+
throw new Error(
|
|
3441
|
+
`Coinalyze closed ${interval2} bar ${new Date(toMs).toISOString()} unavailable for ${missingClosedSymbols.join(",")}`
|
|
3442
|
+
);
|
|
3443
|
+
}
|
|
3333
3444
|
if (rows.length) {
|
|
3334
3445
|
await (0, import_timescale2.upsertDerivatives)(rows);
|
|
3335
3446
|
totalRows += rows.length;
|
|
3336
3447
|
}
|
|
3337
|
-
const
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
(rowsCountBySymbol.get(symbol) ?? 0) + 1
|
|
3343
|
-
);
|
|
3344
|
-
}
|
|
3345
|
-
const coverageRows = missingBatch.map((item) => {
|
|
3346
|
-
const normalizedSymbol = item.symbol.toUpperCase();
|
|
3347
|
-
const rowsCount = rowsCountBySymbol.get(normalizedSymbol) ?? 0;
|
|
3348
|
-
return {
|
|
3349
|
-
source: "coinalyze",
|
|
3350
|
-
symbol: item.symbol,
|
|
3351
|
-
interval: interval2,
|
|
3352
|
-
fromMs: cursor,
|
|
3353
|
-
toMs,
|
|
3354
|
-
rowsCount
|
|
3355
|
-
};
|
|
3448
|
+
const confirmedLiquidationWindow = (0, import_indicators2.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3449
|
+
interval: interval2,
|
|
3450
|
+
fromMs: group.fromMs,
|
|
3451
|
+
toMs,
|
|
3452
|
+
nowMs: coverageNowMs
|
|
3356
3453
|
});
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3454
|
+
if (confirmedLiquidationWindow) {
|
|
3455
|
+
const metricCoverageRows = missingBatch.map((item) => {
|
|
3456
|
+
const marketSymbol = item.marketSymbol.toUpperCase();
|
|
3457
|
+
const eventRowsCount = (liquidationRowsByMarket.get(marketSymbol) ?? []).filter((point) => {
|
|
3458
|
+
const timestamp = (0, import_indicators2.toCoinalyzeTimestampMs)(
|
|
3459
|
+
point.t ?? point.ts ?? point.time ?? point.timestamp
|
|
3460
|
+
);
|
|
3461
|
+
return timestamp != null && timestamp >= confirmedLiquidationWindow.fromMs && timestamp <= confirmedLiquidationWindow.toMs;
|
|
3462
|
+
}).length;
|
|
3463
|
+
return {
|
|
3464
|
+
source: "coinalyze",
|
|
3465
|
+
metric: "liquidation",
|
|
3466
|
+
symbol: item.symbol,
|
|
3467
|
+
interval: interval2,
|
|
3468
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3469
|
+
toMs: confirmedLiquidationWindow.toMs,
|
|
3470
|
+
eventRowsCount
|
|
3471
|
+
};
|
|
3472
|
+
});
|
|
3473
|
+
await (0, import_timescale2.applyDerivativesMetricCoverage)(metricCoverageRows);
|
|
3474
|
+
for (const coverageRow of metricCoverageRows) {
|
|
3475
|
+
const symbol = coverageRow.symbol.toUpperCase();
|
|
3476
|
+
const ranges = liquidationCoverageRangesBySymbol.get(symbol) ?? [];
|
|
3477
|
+
ranges.push({
|
|
3478
|
+
fromMs: coverageRow.fromMs,
|
|
3479
|
+
toMs: coverageRow.toMs
|
|
3480
|
+
});
|
|
3481
|
+
liquidationCoverageRangesBySymbol.set(symbol, ranges);
|
|
3482
|
+
}
|
|
3483
|
+
}
|
|
3484
|
+
if (mode === "backtest") {
|
|
3485
|
+
const rowsCountBySymbol = /* @__PURE__ */ new Map();
|
|
3486
|
+
for (const row of rows) {
|
|
3487
|
+
const symbol = row.symbol.toUpperCase();
|
|
3488
|
+
rowsCountBySymbol.set(
|
|
3366
3489
|
symbol,
|
|
3490
|
+
(rowsCountBySymbol.get(symbol) ?? 0) + 1
|
|
3491
|
+
);
|
|
3492
|
+
}
|
|
3493
|
+
const coverageRows = missingBatch.map((item) => {
|
|
3494
|
+
const normalizedSymbol = item.symbol.toUpperCase();
|
|
3495
|
+
const rowsCount = rowsCountBySymbol.get(normalizedSymbol) ?? 0;
|
|
3496
|
+
return {
|
|
3497
|
+
source: "coinalyze",
|
|
3498
|
+
symbol: item.symbol,
|
|
3367
3499
|
interval: interval2,
|
|
3368
3500
|
fromMs: cursor,
|
|
3369
|
-
toMs
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3501
|
+
toMs,
|
|
3502
|
+
rowsCount
|
|
3503
|
+
};
|
|
3504
|
+
});
|
|
3505
|
+
await (0, import_timescale2.upsertDerivativesBackfillCoverage)(coverageRows);
|
|
3506
|
+
for (const coverageRow of coverageRows) {
|
|
3507
|
+
const symbol = coverageRow.symbol.toUpperCase();
|
|
3508
|
+
edgesBySymbol.set(
|
|
3509
|
+
symbol,
|
|
3510
|
+
extendEdges(edgesBySymbol.get(symbol), cursor, toMs)
|
|
3511
|
+
);
|
|
3512
|
+
coverageKeys.add(
|
|
3513
|
+
coverageKey({
|
|
3514
|
+
symbol,
|
|
3515
|
+
interval: interval2,
|
|
3516
|
+
fromMs: cursor,
|
|
3517
|
+
toMs
|
|
3518
|
+
})
|
|
3519
|
+
);
|
|
3520
|
+
const coverageRanges = coverageRangesBySymbol.get(symbol) ?? [];
|
|
3521
|
+
coverageRanges.push({ fromMs: cursor, toMs });
|
|
3522
|
+
coverageRangesBySymbol.set(symbol, coverageRanges);
|
|
3523
|
+
}
|
|
3375
3524
|
}
|
|
3376
3525
|
}
|
|
3377
3526
|
}
|