@tradejs/cli 2.0.1 → 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 +250 -38
- package/dist/lib/aiTrainCharts.js +49 -2
- package/dist/lib/aiTrainMetrics.js +49 -2
- package/dist/lib/aiTrainResearch.js +58 -3
- package/dist/lib/derivativesContextBackfill.js +143 -32
- package/dist/lib/marketContextPrepare.js +141 -32
- package/dist/scripts/aiPocketSearch.js +49 -2
- package/dist/scripts/aiTrain.js +76 -3
- package/dist/scripts/backtest.js +141 -32
- package/dist/scripts/derivativesIngestCoinalyzeAll.js +30 -0
- package/dist/scripts/replay.js +141 -32
- package/dist/scripts/replayRunner.js +141 -32
- package/dist/scripts/runtimeParity.js +141 -32
- package/dist/scripts/signals.js +141 -32
- package/dist/scripts/signalsDaemon.js +141 -32
- package/package.json +9 -9
package/dist/scripts/backtest.js
CHANGED
|
@@ -2613,6 +2613,38 @@ var resolveDerivativesContextMissingFetchFromMs = (params) => {
|
|
|
2613
2613
|
return null;
|
|
2614
2614
|
};
|
|
2615
2615
|
var resolveDerivativesContextFetchFromMs = (params) => resolveDerivativesContextMissingFetchFromMs(params) ?? (params.refreshClosedTail ? params.toMs : null);
|
|
2616
|
+
var resolveDerivativesContextRequiredFetchFromMs = (params) => {
|
|
2617
|
+
const dataCoverageFromMs = params.dataCoverageKeyExists ? null : params.mode === "signals" ? params.fromMs : resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
2618
|
+
ranges: params.dataCoverageRanges,
|
|
2619
|
+
fromMs: params.fromMs,
|
|
2620
|
+
toMs: params.toMs,
|
|
2621
|
+
intervalMs: params.intervalMs
|
|
2622
|
+
});
|
|
2623
|
+
const edgesFromMs = dataCoverageFromMs == null ? null : resolveDerivativesContextFetchFromMs({
|
|
2624
|
+
edges: params.edges,
|
|
2625
|
+
fromMs: params.fromMs,
|
|
2626
|
+
toMs: params.toMs,
|
|
2627
|
+
intervalMs: params.intervalMs,
|
|
2628
|
+
refreshClosedTail: params.mode === "signals"
|
|
2629
|
+
});
|
|
2630
|
+
const dataFetchFromMs = dataCoverageFromMs != null && edgesFromMs != null ? Math.max(dataCoverageFromMs, edgesFromMs) : null;
|
|
2631
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
2632
|
+
interval: params.interval,
|
|
2633
|
+
fromMs: params.fromMs,
|
|
2634
|
+
toMs: params.toMs,
|
|
2635
|
+
nowMs: params.nowMs
|
|
2636
|
+
});
|
|
2637
|
+
const liquidationFetchFromMs = confirmedLiquidationWindow ? resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
2638
|
+
ranges: params.liquidationCoverageRanges,
|
|
2639
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
2640
|
+
toMs: confirmedLiquidationWindow.toMs,
|
|
2641
|
+
intervalMs: params.intervalMs
|
|
2642
|
+
}) : null;
|
|
2643
|
+
const fetchStarts = [dataFetchFromMs, liquidationFetchFromMs].filter(
|
|
2644
|
+
(value) => value != null
|
|
2645
|
+
);
|
|
2646
|
+
return fetchStarts.length ? Math.min(...fetchStarts) : null;
|
|
2647
|
+
};
|
|
2616
2648
|
var countBackfillWindows = (params) => {
|
|
2617
2649
|
let count = 0;
|
|
2618
2650
|
let cursor = params.fromMs;
|
|
@@ -2948,7 +2980,8 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
2948
2980
|
mode,
|
|
2949
2981
|
startMs,
|
|
2950
2982
|
endMs,
|
|
2951
|
-
preloadStartMs: params.preloadStartMs
|
|
2983
|
+
preloadStartMs: params.preloadStartMs,
|
|
2984
|
+
nowMs: Date.now()
|
|
2952
2985
|
});
|
|
2953
2986
|
if (safeEndMs <= fromMs) {
|
|
2954
2987
|
return skippedBackfillResult2();
|
|
@@ -2982,15 +3015,33 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
2982
3015
|
);
|
|
2983
3016
|
const coverageKeysByInterval = /* @__PURE__ */ new Map();
|
|
2984
3017
|
const coverageRangesByInterval = /* @__PURE__ */ new Map();
|
|
3018
|
+
const liquidationCoverageRangesByInterval = /* @__PURE__ */ new Map();
|
|
3019
|
+
const coverageNowMs = Date.now();
|
|
2985
3020
|
await Promise.all(
|
|
2986
3021
|
intervalWindows.map(async (window2) => {
|
|
2987
|
-
const
|
|
2988
|
-
source: "coinalyze",
|
|
2989
|
-
symbols,
|
|
3022
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
2990
3023
|
interval: window2.interval,
|
|
2991
3024
|
fromMs: window2.fromMs,
|
|
2992
|
-
toMs: window2.toMs
|
|
3025
|
+
toMs: window2.toMs,
|
|
3026
|
+
nowMs: coverageNowMs
|
|
2993
3027
|
});
|
|
3028
|
+
const [coverageRows, liquidationCoverageRows] = await Promise.all([
|
|
3029
|
+
(0, import_timescale2.getDerivativesBackfillCoverage)({
|
|
3030
|
+
source: "coinalyze",
|
|
3031
|
+
symbols,
|
|
3032
|
+
interval: window2.interval,
|
|
3033
|
+
fromMs: window2.fromMs,
|
|
3034
|
+
toMs: window2.toMs
|
|
3035
|
+
}),
|
|
3036
|
+
confirmedLiquidationWindow ? (0, import_timescale2.getDerivativesMetricCoverage)({
|
|
3037
|
+
source: "coinalyze",
|
|
3038
|
+
metric: "liquidation",
|
|
3039
|
+
symbols,
|
|
3040
|
+
interval: window2.interval,
|
|
3041
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3042
|
+
toMs: confirmedLiquidationWindow.toMs
|
|
3043
|
+
}) : Promise.resolve([])
|
|
3044
|
+
]);
|
|
2994
3045
|
coverageKeysByInterval.set(
|
|
2995
3046
|
window2.interval,
|
|
2996
3047
|
new Set(
|
|
@@ -3012,6 +3063,17 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3012
3063
|
rangesBySymbol.set(symbol, ranges);
|
|
3013
3064
|
}
|
|
3014
3065
|
coverageRangesByInterval.set(window2.interval, rangesBySymbol);
|
|
3066
|
+
const liquidationRangesBySymbol = /* @__PURE__ */ new Map();
|
|
3067
|
+
for (const row of liquidationCoverageRows) {
|
|
3068
|
+
const symbol = row.symbol.toUpperCase();
|
|
3069
|
+
const ranges = liquidationRangesBySymbol.get(symbol) ?? [];
|
|
3070
|
+
ranges.push({ fromMs: row.fromMs, toMs: row.toMs });
|
|
3071
|
+
liquidationRangesBySymbol.set(symbol, ranges);
|
|
3072
|
+
}
|
|
3073
|
+
liquidationCoverageRangesByInterval.set(
|
|
3074
|
+
window2.interval,
|
|
3075
|
+
liquidationRangesBySymbol
|
|
3076
|
+
);
|
|
3015
3077
|
})
|
|
3016
3078
|
);
|
|
3017
3079
|
const cachedWindows = intervalWindows.reduce(
|
|
@@ -3036,7 +3098,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3036
3098
|
(symbol) => backfillWindows.every((backfillWindow) => {
|
|
3037
3099
|
const normalizedSymbol = symbol.toUpperCase();
|
|
3038
3100
|
const coverageRanges = coverageRangesByInterval.get(window2.interval)?.get(normalizedSymbol) ?? [];
|
|
3039
|
-
|
|
3101
|
+
const dataCovered = hasDerivativesWindowCoverage({
|
|
3040
3102
|
edges: edgesBySymbol?.get(normalizedSymbol),
|
|
3041
3103
|
fromMs: backfillWindow.fromMs,
|
|
3042
3104
|
toMs: backfillWindow.toMs
|
|
@@ -3053,6 +3115,19 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3053
3115
|
toMs: backfillWindow.toMs
|
|
3054
3116
|
})
|
|
3055
3117
|
);
|
|
3118
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3119
|
+
interval: window2.interval,
|
|
3120
|
+
fromMs: backfillWindow.fromMs,
|
|
3121
|
+
toMs: backfillWindow.toMs,
|
|
3122
|
+
nowMs: coverageNowMs
|
|
3123
|
+
});
|
|
3124
|
+
const liquidationCovered = confirmedLiquidationWindow == null || resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
3125
|
+
ranges: liquidationCoverageRangesByInterval.get(window2.interval)?.get(normalizedSymbol) ?? [],
|
|
3126
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3127
|
+
toMs: confirmedLiquidationWindow.toMs,
|
|
3128
|
+
intervalMs: window2.intervalMs
|
|
3129
|
+
}) == null;
|
|
3130
|
+
return dataCovered && liquidationCovered;
|
|
3056
3131
|
})
|
|
3057
3132
|
);
|
|
3058
3133
|
});
|
|
@@ -3137,6 +3212,11 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3137
3212
|
coverageKeysByInterval.set(interval2, coverageKeys);
|
|
3138
3213
|
const coverageRangesBySymbol = coverageRangesByInterval.get(interval2) ?? /* @__PURE__ */ new Map();
|
|
3139
3214
|
coverageRangesByInterval.set(interval2, coverageRangesBySymbol);
|
|
3215
|
+
const liquidationCoverageRangesBySymbol = liquidationCoverageRangesByInterval.get(interval2) ?? /* @__PURE__ */ new Map();
|
|
3216
|
+
liquidationCoverageRangesByInterval.set(
|
|
3217
|
+
interval2,
|
|
3218
|
+
liquidationCoverageRangesBySymbol
|
|
3219
|
+
);
|
|
3140
3220
|
for (let batchIdx = 0; batchIdx < symbolBatches.length; batchIdx += 1) {
|
|
3141
3221
|
const batch = symbolBatches[batchIdx];
|
|
3142
3222
|
let cursor = window2.fromMs;
|
|
@@ -3149,33 +3229,25 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3149
3229
|
fromMs: cursor,
|
|
3150
3230
|
toMs
|
|
3151
3231
|
});
|
|
3152
|
-
if (coverageKeys.has(key)) {
|
|
3153
|
-
return null;
|
|
3154
|
-
}
|
|
3155
3232
|
const normalizedSymbol = item.symbol.toUpperCase();
|
|
3156
|
-
const
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
refreshClosedTail: mode === "signals"
|
|
3172
|
-
});
|
|
3173
|
-
if (edgesFromMs == null) {
|
|
3174
|
-
return null;
|
|
3175
|
-
}
|
|
3233
|
+
const requiredFromMs = resolveDerivativesContextRequiredFetchFromMs(
|
|
3234
|
+
{
|
|
3235
|
+
mode,
|
|
3236
|
+
interval: interval2,
|
|
3237
|
+
intervalMs,
|
|
3238
|
+
fromMs: cursor,
|
|
3239
|
+
toMs,
|
|
3240
|
+
nowMs: coverageNowMs,
|
|
3241
|
+
dataCoverageKeyExists: coverageKeys.has(key),
|
|
3242
|
+
dataCoverageRanges: coverageRangesBySymbol.get(normalizedSymbol),
|
|
3243
|
+
liquidationCoverageRanges: liquidationCoverageRangesBySymbol.get(normalizedSymbol),
|
|
3244
|
+
edges: edgesBySymbol.get(normalizedSymbol)
|
|
3245
|
+
}
|
|
3246
|
+
);
|
|
3247
|
+
if (requiredFromMs == null) return null;
|
|
3176
3248
|
return {
|
|
3177
3249
|
item,
|
|
3178
|
-
fromMs:
|
|
3250
|
+
fromMs: requiredFromMs
|
|
3179
3251
|
};
|
|
3180
3252
|
}).filter(
|
|
3181
3253
|
(item) => item != null
|
|
@@ -3200,6 +3272,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3200
3272
|
);
|
|
3201
3273
|
let rows = [];
|
|
3202
3274
|
let missingClosedSymbols = [];
|
|
3275
|
+
let liquidationRowsByMarket = /* @__PURE__ */ new Map();
|
|
3203
3276
|
for (let attempt = 1; attempt <= maxClosedBarAttempts; attempt += 1) {
|
|
3204
3277
|
const oiMap = await fetchMetricBatch({
|
|
3205
3278
|
endpoint: oiPath,
|
|
@@ -3219,7 +3292,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3219
3292
|
fromMs: group.fromMs,
|
|
3220
3293
|
toMs
|
|
3221
3294
|
});
|
|
3222
|
-
|
|
3295
|
+
liquidationRowsByMarket = await fetchMetricBatch({
|
|
3223
3296
|
endpoint: liqPath,
|
|
3224
3297
|
metric: "liq",
|
|
3225
3298
|
marketSymbols,
|
|
@@ -3234,7 +3307,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3234
3307
|
symbol: item.symbol,
|
|
3235
3308
|
oiRaw: oiMap.get(marketSymbol) ?? [],
|
|
3236
3309
|
fundingRaw: fundingMap.get(marketSymbol) ?? [],
|
|
3237
|
-
liqRaw:
|
|
3310
|
+
liqRaw: liquidationRowsByMarket.get(marketSymbol) ?? []
|
|
3238
3311
|
});
|
|
3239
3312
|
return (0, import_indicators.coinalyzePointsToRows)(points, interval2, "coinalyze");
|
|
3240
3313
|
});
|
|
@@ -3257,6 +3330,42 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3257
3330
|
await (0, import_timescale2.upsertDerivatives)(rows);
|
|
3258
3331
|
totalRows += rows.length;
|
|
3259
3332
|
}
|
|
3333
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3334
|
+
interval: interval2,
|
|
3335
|
+
fromMs: group.fromMs,
|
|
3336
|
+
toMs,
|
|
3337
|
+
nowMs: coverageNowMs
|
|
3338
|
+
});
|
|
3339
|
+
if (confirmedLiquidationWindow) {
|
|
3340
|
+
const metricCoverageRows = missingBatch.map((item) => {
|
|
3341
|
+
const marketSymbol = item.marketSymbol.toUpperCase();
|
|
3342
|
+
const eventRowsCount = (liquidationRowsByMarket.get(marketSymbol) ?? []).filter((point) => {
|
|
3343
|
+
const timestamp = (0, import_indicators.toCoinalyzeTimestampMs)(
|
|
3344
|
+
point.t ?? point.ts ?? point.time ?? point.timestamp
|
|
3345
|
+
);
|
|
3346
|
+
return timestamp != null && timestamp >= confirmedLiquidationWindow.fromMs && timestamp <= confirmedLiquidationWindow.toMs;
|
|
3347
|
+
}).length;
|
|
3348
|
+
return {
|
|
3349
|
+
source: "coinalyze",
|
|
3350
|
+
metric: "liquidation",
|
|
3351
|
+
symbol: item.symbol,
|
|
3352
|
+
interval: interval2,
|
|
3353
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3354
|
+
toMs: confirmedLiquidationWindow.toMs,
|
|
3355
|
+
eventRowsCount
|
|
3356
|
+
};
|
|
3357
|
+
});
|
|
3358
|
+
await (0, import_timescale2.applyDerivativesMetricCoverage)(metricCoverageRows);
|
|
3359
|
+
for (const coverageRow of metricCoverageRows) {
|
|
3360
|
+
const symbol = coverageRow.symbol.toUpperCase();
|
|
3361
|
+
const ranges = liquidationCoverageRangesBySymbol.get(symbol) ?? [];
|
|
3362
|
+
ranges.push({
|
|
3363
|
+
fromMs: coverageRow.fromMs,
|
|
3364
|
+
toMs: coverageRow.toMs
|
|
3365
|
+
});
|
|
3366
|
+
liquidationCoverageRangesBySymbol.set(symbol, ranges);
|
|
3367
|
+
}
|
|
3368
|
+
}
|
|
3260
3369
|
if (mode === "backtest") {
|
|
3261
3370
|
const rowsCountBySymbol = /* @__PURE__ */ new Map();
|
|
3262
3371
|
for (const row of rows) {
|
|
@@ -378,6 +378,36 @@ var main = async () => {
|
|
|
378
378
|
await (0, import_timescale.upsertDerivatives)(rows);
|
|
379
379
|
totalRows += rows.length;
|
|
380
380
|
}
|
|
381
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
382
|
+
interval,
|
|
383
|
+
fromMs: cursor,
|
|
384
|
+
toMs,
|
|
385
|
+
nowMs: now
|
|
386
|
+
});
|
|
387
|
+
if (confirmedLiquidationWindow) {
|
|
388
|
+
await (0, import_timescale.applyDerivativesMetricCoverage)(
|
|
389
|
+
batch.map((item) => {
|
|
390
|
+
const marketSymbol = item.marketSymbol.toUpperCase();
|
|
391
|
+
const eventRowsCount = (liqMap.get(marketSymbol) ?? []).filter(
|
|
392
|
+
(point) => {
|
|
393
|
+
const timestamp = (0, import_indicators.toCoinalyzeTimestampMs)(
|
|
394
|
+
point.t ?? point.ts ?? point.time ?? point.timestamp
|
|
395
|
+
);
|
|
396
|
+
return timestamp != null && timestamp >= confirmedLiquidationWindow.fromMs && timestamp <= confirmedLiquidationWindow.toMs;
|
|
397
|
+
}
|
|
398
|
+
).length;
|
|
399
|
+
return {
|
|
400
|
+
source: "coinalyze",
|
|
401
|
+
metric: "liquidation",
|
|
402
|
+
symbol: item.symbol,
|
|
403
|
+
interval,
|
|
404
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
405
|
+
toMs: confirmedLiquidationWindow.toMs,
|
|
406
|
+
eventRowsCount
|
|
407
|
+
};
|
|
408
|
+
})
|
|
409
|
+
);
|
|
410
|
+
}
|
|
381
411
|
} catch (error) {
|
|
382
412
|
failedWindows += 1;
|
|
383
413
|
console.error(
|
package/dist/scripts/replay.js
CHANGED
|
@@ -3224,6 +3224,38 @@ var resolveDerivativesContextMissingFetchFromMs = (params) => {
|
|
|
3224
3224
|
return null;
|
|
3225
3225
|
};
|
|
3226
3226
|
var resolveDerivativesContextFetchFromMs = (params) => resolveDerivativesContextMissingFetchFromMs(params) ?? (params.refreshClosedTail ? params.toMs : null);
|
|
3227
|
+
var resolveDerivativesContextRequiredFetchFromMs = (params) => {
|
|
3228
|
+
const dataCoverageFromMs = params.dataCoverageKeyExists ? null : params.mode === "signals" ? params.fromMs : resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
3229
|
+
ranges: params.dataCoverageRanges,
|
|
3230
|
+
fromMs: params.fromMs,
|
|
3231
|
+
toMs: params.toMs,
|
|
3232
|
+
intervalMs: params.intervalMs
|
|
3233
|
+
});
|
|
3234
|
+
const edgesFromMs = dataCoverageFromMs == null ? null : resolveDerivativesContextFetchFromMs({
|
|
3235
|
+
edges: params.edges,
|
|
3236
|
+
fromMs: params.fromMs,
|
|
3237
|
+
toMs: params.toMs,
|
|
3238
|
+
intervalMs: params.intervalMs,
|
|
3239
|
+
refreshClosedTail: params.mode === "signals"
|
|
3240
|
+
});
|
|
3241
|
+
const dataFetchFromMs = dataCoverageFromMs != null && edgesFromMs != null ? Math.max(dataCoverageFromMs, edgesFromMs) : null;
|
|
3242
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3243
|
+
interval: params.interval,
|
|
3244
|
+
fromMs: params.fromMs,
|
|
3245
|
+
toMs: params.toMs,
|
|
3246
|
+
nowMs: params.nowMs
|
|
3247
|
+
});
|
|
3248
|
+
const liquidationFetchFromMs = confirmedLiquidationWindow ? resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
3249
|
+
ranges: params.liquidationCoverageRanges,
|
|
3250
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3251
|
+
toMs: confirmedLiquidationWindow.toMs,
|
|
3252
|
+
intervalMs: params.intervalMs
|
|
3253
|
+
}) : null;
|
|
3254
|
+
const fetchStarts = [dataFetchFromMs, liquidationFetchFromMs].filter(
|
|
3255
|
+
(value) => value != null
|
|
3256
|
+
);
|
|
3257
|
+
return fetchStarts.length ? Math.min(...fetchStarts) : null;
|
|
3258
|
+
};
|
|
3227
3259
|
var countBackfillWindows = (params) => {
|
|
3228
3260
|
let count = 0;
|
|
3229
3261
|
let cursor = params.fromMs;
|
|
@@ -3559,7 +3591,8 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3559
3591
|
mode,
|
|
3560
3592
|
startMs,
|
|
3561
3593
|
endMs,
|
|
3562
|
-
preloadStartMs: params.preloadStartMs
|
|
3594
|
+
preloadStartMs: params.preloadStartMs,
|
|
3595
|
+
nowMs: Date.now()
|
|
3563
3596
|
});
|
|
3564
3597
|
if (safeEndMs <= fromMs) {
|
|
3565
3598
|
return skippedBackfillResult2();
|
|
@@ -3593,15 +3626,33 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3593
3626
|
);
|
|
3594
3627
|
const coverageKeysByInterval = /* @__PURE__ */ new Map();
|
|
3595
3628
|
const coverageRangesByInterval = /* @__PURE__ */ new Map();
|
|
3629
|
+
const liquidationCoverageRangesByInterval = /* @__PURE__ */ new Map();
|
|
3630
|
+
const coverageNowMs = Date.now();
|
|
3596
3631
|
await Promise.all(
|
|
3597
3632
|
intervalWindows.map(async (window2) => {
|
|
3598
|
-
const
|
|
3599
|
-
source: "coinalyze",
|
|
3600
|
-
symbols,
|
|
3633
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3601
3634
|
interval: window2.interval,
|
|
3602
3635
|
fromMs: window2.fromMs,
|
|
3603
|
-
toMs: window2.toMs
|
|
3636
|
+
toMs: window2.toMs,
|
|
3637
|
+
nowMs: coverageNowMs
|
|
3604
3638
|
});
|
|
3639
|
+
const [coverageRows, liquidationCoverageRows] = await Promise.all([
|
|
3640
|
+
(0, import_timescale2.getDerivativesBackfillCoverage)({
|
|
3641
|
+
source: "coinalyze",
|
|
3642
|
+
symbols,
|
|
3643
|
+
interval: window2.interval,
|
|
3644
|
+
fromMs: window2.fromMs,
|
|
3645
|
+
toMs: window2.toMs
|
|
3646
|
+
}),
|
|
3647
|
+
confirmedLiquidationWindow ? (0, import_timescale2.getDerivativesMetricCoverage)({
|
|
3648
|
+
source: "coinalyze",
|
|
3649
|
+
metric: "liquidation",
|
|
3650
|
+
symbols,
|
|
3651
|
+
interval: window2.interval,
|
|
3652
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3653
|
+
toMs: confirmedLiquidationWindow.toMs
|
|
3654
|
+
}) : Promise.resolve([])
|
|
3655
|
+
]);
|
|
3605
3656
|
coverageKeysByInterval.set(
|
|
3606
3657
|
window2.interval,
|
|
3607
3658
|
new Set(
|
|
@@ -3623,6 +3674,17 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3623
3674
|
rangesBySymbol.set(symbol, ranges);
|
|
3624
3675
|
}
|
|
3625
3676
|
coverageRangesByInterval.set(window2.interval, rangesBySymbol);
|
|
3677
|
+
const liquidationRangesBySymbol = /* @__PURE__ */ new Map();
|
|
3678
|
+
for (const row of liquidationCoverageRows) {
|
|
3679
|
+
const symbol = row.symbol.toUpperCase();
|
|
3680
|
+
const ranges = liquidationRangesBySymbol.get(symbol) ?? [];
|
|
3681
|
+
ranges.push({ fromMs: row.fromMs, toMs: row.toMs });
|
|
3682
|
+
liquidationRangesBySymbol.set(symbol, ranges);
|
|
3683
|
+
}
|
|
3684
|
+
liquidationCoverageRangesByInterval.set(
|
|
3685
|
+
window2.interval,
|
|
3686
|
+
liquidationRangesBySymbol
|
|
3687
|
+
);
|
|
3626
3688
|
})
|
|
3627
3689
|
);
|
|
3628
3690
|
const cachedWindows = intervalWindows.reduce(
|
|
@@ -3647,7 +3709,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3647
3709
|
(symbol) => backfillWindows.every((backfillWindow) => {
|
|
3648
3710
|
const normalizedSymbol = symbol.toUpperCase();
|
|
3649
3711
|
const coverageRanges = coverageRangesByInterval.get(window2.interval)?.get(normalizedSymbol) ?? [];
|
|
3650
|
-
|
|
3712
|
+
const dataCovered = hasDerivativesWindowCoverage({
|
|
3651
3713
|
edges: edgesBySymbol?.get(normalizedSymbol),
|
|
3652
3714
|
fromMs: backfillWindow.fromMs,
|
|
3653
3715
|
toMs: backfillWindow.toMs
|
|
@@ -3664,6 +3726,19 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3664
3726
|
toMs: backfillWindow.toMs
|
|
3665
3727
|
})
|
|
3666
3728
|
);
|
|
3729
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3730
|
+
interval: window2.interval,
|
|
3731
|
+
fromMs: backfillWindow.fromMs,
|
|
3732
|
+
toMs: backfillWindow.toMs,
|
|
3733
|
+
nowMs: coverageNowMs
|
|
3734
|
+
});
|
|
3735
|
+
const liquidationCovered = confirmedLiquidationWindow == null || resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
3736
|
+
ranges: liquidationCoverageRangesByInterval.get(window2.interval)?.get(normalizedSymbol) ?? [],
|
|
3737
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3738
|
+
toMs: confirmedLiquidationWindow.toMs,
|
|
3739
|
+
intervalMs: window2.intervalMs
|
|
3740
|
+
}) == null;
|
|
3741
|
+
return dataCovered && liquidationCovered;
|
|
3667
3742
|
})
|
|
3668
3743
|
);
|
|
3669
3744
|
});
|
|
@@ -3748,6 +3823,11 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3748
3823
|
coverageKeysByInterval.set(interval, coverageKeys);
|
|
3749
3824
|
const coverageRangesBySymbol = coverageRangesByInterval.get(interval) ?? /* @__PURE__ */ new Map();
|
|
3750
3825
|
coverageRangesByInterval.set(interval, coverageRangesBySymbol);
|
|
3826
|
+
const liquidationCoverageRangesBySymbol = liquidationCoverageRangesByInterval.get(interval) ?? /* @__PURE__ */ new Map();
|
|
3827
|
+
liquidationCoverageRangesByInterval.set(
|
|
3828
|
+
interval,
|
|
3829
|
+
liquidationCoverageRangesBySymbol
|
|
3830
|
+
);
|
|
3751
3831
|
for (let batchIdx = 0; batchIdx < symbolBatches.length; batchIdx += 1) {
|
|
3752
3832
|
const batch = symbolBatches[batchIdx];
|
|
3753
3833
|
let cursor = window2.fromMs;
|
|
@@ -3760,33 +3840,25 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3760
3840
|
fromMs: cursor,
|
|
3761
3841
|
toMs
|
|
3762
3842
|
});
|
|
3763
|
-
if (coverageKeys.has(key)) {
|
|
3764
|
-
return null;
|
|
3765
|
-
}
|
|
3766
3843
|
const normalizedSymbol = item.symbol.toUpperCase();
|
|
3767
|
-
const
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
refreshClosedTail: mode === "signals"
|
|
3783
|
-
});
|
|
3784
|
-
if (edgesFromMs == null) {
|
|
3785
|
-
return null;
|
|
3786
|
-
}
|
|
3844
|
+
const requiredFromMs = resolveDerivativesContextRequiredFetchFromMs(
|
|
3845
|
+
{
|
|
3846
|
+
mode,
|
|
3847
|
+
interval,
|
|
3848
|
+
intervalMs,
|
|
3849
|
+
fromMs: cursor,
|
|
3850
|
+
toMs,
|
|
3851
|
+
nowMs: coverageNowMs,
|
|
3852
|
+
dataCoverageKeyExists: coverageKeys.has(key),
|
|
3853
|
+
dataCoverageRanges: coverageRangesBySymbol.get(normalizedSymbol),
|
|
3854
|
+
liquidationCoverageRanges: liquidationCoverageRangesBySymbol.get(normalizedSymbol),
|
|
3855
|
+
edges: edgesBySymbol.get(normalizedSymbol)
|
|
3856
|
+
}
|
|
3857
|
+
);
|
|
3858
|
+
if (requiredFromMs == null) return null;
|
|
3787
3859
|
return {
|
|
3788
3860
|
item,
|
|
3789
|
-
fromMs:
|
|
3861
|
+
fromMs: requiredFromMs
|
|
3790
3862
|
};
|
|
3791
3863
|
}).filter(
|
|
3792
3864
|
(item) => item != null
|
|
@@ -3811,6 +3883,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3811
3883
|
);
|
|
3812
3884
|
let rows = [];
|
|
3813
3885
|
let missingClosedSymbols = [];
|
|
3886
|
+
let liquidationRowsByMarket = /* @__PURE__ */ new Map();
|
|
3814
3887
|
for (let attempt = 1; attempt <= maxClosedBarAttempts; attempt += 1) {
|
|
3815
3888
|
const oiMap = await fetchMetricBatch({
|
|
3816
3889
|
endpoint: oiPath,
|
|
@@ -3830,7 +3903,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3830
3903
|
fromMs: group.fromMs,
|
|
3831
3904
|
toMs
|
|
3832
3905
|
});
|
|
3833
|
-
|
|
3906
|
+
liquidationRowsByMarket = await fetchMetricBatch({
|
|
3834
3907
|
endpoint: liqPath,
|
|
3835
3908
|
metric: "liq",
|
|
3836
3909
|
marketSymbols,
|
|
@@ -3845,7 +3918,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3845
3918
|
symbol: item.symbol,
|
|
3846
3919
|
oiRaw: oiMap.get(marketSymbol) ?? [],
|
|
3847
3920
|
fundingRaw: fundingMap.get(marketSymbol) ?? [],
|
|
3848
|
-
liqRaw:
|
|
3921
|
+
liqRaw: liquidationRowsByMarket.get(marketSymbol) ?? []
|
|
3849
3922
|
});
|
|
3850
3923
|
return (0, import_indicators.coinalyzePointsToRows)(points, interval, "coinalyze");
|
|
3851
3924
|
});
|
|
@@ -3868,6 +3941,42 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3868
3941
|
await (0, import_timescale2.upsertDerivatives)(rows);
|
|
3869
3942
|
totalRows += rows.length;
|
|
3870
3943
|
}
|
|
3944
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3945
|
+
interval,
|
|
3946
|
+
fromMs: group.fromMs,
|
|
3947
|
+
toMs,
|
|
3948
|
+
nowMs: coverageNowMs
|
|
3949
|
+
});
|
|
3950
|
+
if (confirmedLiquidationWindow) {
|
|
3951
|
+
const metricCoverageRows = missingBatch.map((item) => {
|
|
3952
|
+
const marketSymbol = item.marketSymbol.toUpperCase();
|
|
3953
|
+
const eventRowsCount = (liquidationRowsByMarket.get(marketSymbol) ?? []).filter((point) => {
|
|
3954
|
+
const timestamp = (0, import_indicators.toCoinalyzeTimestampMs)(
|
|
3955
|
+
point.t ?? point.ts ?? point.time ?? point.timestamp
|
|
3956
|
+
);
|
|
3957
|
+
return timestamp != null && timestamp >= confirmedLiquidationWindow.fromMs && timestamp <= confirmedLiquidationWindow.toMs;
|
|
3958
|
+
}).length;
|
|
3959
|
+
return {
|
|
3960
|
+
source: "coinalyze",
|
|
3961
|
+
metric: "liquidation",
|
|
3962
|
+
symbol: item.symbol,
|
|
3963
|
+
interval,
|
|
3964
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3965
|
+
toMs: confirmedLiquidationWindow.toMs,
|
|
3966
|
+
eventRowsCount
|
|
3967
|
+
};
|
|
3968
|
+
});
|
|
3969
|
+
await (0, import_timescale2.applyDerivativesMetricCoverage)(metricCoverageRows);
|
|
3970
|
+
for (const coverageRow of metricCoverageRows) {
|
|
3971
|
+
const symbol = coverageRow.symbol.toUpperCase();
|
|
3972
|
+
const ranges = liquidationCoverageRangesBySymbol.get(symbol) ?? [];
|
|
3973
|
+
ranges.push({
|
|
3974
|
+
fromMs: coverageRow.fromMs,
|
|
3975
|
+
toMs: coverageRow.toMs
|
|
3976
|
+
});
|
|
3977
|
+
liquidationCoverageRangesBySymbol.set(symbol, ranges);
|
|
3978
|
+
}
|
|
3979
|
+
}
|
|
3871
3980
|
if (mode === "backtest") {
|
|
3872
3981
|
const rowsCountBySymbol = /* @__PURE__ */ new Map();
|
|
3873
3982
|
for (const row of rows) {
|