@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
|
@@ -3227,6 +3227,38 @@ var resolveDerivativesContextMissingFetchFromMs = (params) => {
|
|
|
3227
3227
|
return null;
|
|
3228
3228
|
};
|
|
3229
3229
|
var resolveDerivativesContextFetchFromMs = (params) => resolveDerivativesContextMissingFetchFromMs(params) ?? (params.refreshClosedTail ? params.toMs : null);
|
|
3230
|
+
var resolveDerivativesContextRequiredFetchFromMs = (params) => {
|
|
3231
|
+
const dataCoverageFromMs = params.dataCoverageKeyExists ? null : params.mode === "signals" ? params.fromMs : resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
3232
|
+
ranges: params.dataCoverageRanges,
|
|
3233
|
+
fromMs: params.fromMs,
|
|
3234
|
+
toMs: params.toMs,
|
|
3235
|
+
intervalMs: params.intervalMs
|
|
3236
|
+
});
|
|
3237
|
+
const edgesFromMs = dataCoverageFromMs == null ? null : resolveDerivativesContextFetchFromMs({
|
|
3238
|
+
edges: params.edges,
|
|
3239
|
+
fromMs: params.fromMs,
|
|
3240
|
+
toMs: params.toMs,
|
|
3241
|
+
intervalMs: params.intervalMs,
|
|
3242
|
+
refreshClosedTail: params.mode === "signals"
|
|
3243
|
+
});
|
|
3244
|
+
const dataFetchFromMs = dataCoverageFromMs != null && edgesFromMs != null ? Math.max(dataCoverageFromMs, edgesFromMs) : null;
|
|
3245
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3246
|
+
interval: params.interval,
|
|
3247
|
+
fromMs: params.fromMs,
|
|
3248
|
+
toMs: params.toMs,
|
|
3249
|
+
nowMs: params.nowMs
|
|
3250
|
+
});
|
|
3251
|
+
const liquidationFetchFromMs = confirmedLiquidationWindow ? resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
3252
|
+
ranges: params.liquidationCoverageRanges,
|
|
3253
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3254
|
+
toMs: confirmedLiquidationWindow.toMs,
|
|
3255
|
+
intervalMs: params.intervalMs
|
|
3256
|
+
}) : null;
|
|
3257
|
+
const fetchStarts = [dataFetchFromMs, liquidationFetchFromMs].filter(
|
|
3258
|
+
(value) => value != null
|
|
3259
|
+
);
|
|
3260
|
+
return fetchStarts.length ? Math.min(...fetchStarts) : null;
|
|
3261
|
+
};
|
|
3230
3262
|
var countBackfillWindows = (params) => {
|
|
3231
3263
|
let count = 0;
|
|
3232
3264
|
let cursor = params.fromMs;
|
|
@@ -3562,7 +3594,8 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3562
3594
|
mode,
|
|
3563
3595
|
startMs,
|
|
3564
3596
|
endMs,
|
|
3565
|
-
preloadStartMs: params.preloadStartMs
|
|
3597
|
+
preloadStartMs: params.preloadStartMs,
|
|
3598
|
+
nowMs: Date.now()
|
|
3566
3599
|
});
|
|
3567
3600
|
if (safeEndMs <= fromMs) {
|
|
3568
3601
|
return skippedBackfillResult2();
|
|
@@ -3596,15 +3629,33 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3596
3629
|
);
|
|
3597
3630
|
const coverageKeysByInterval = /* @__PURE__ */ new Map();
|
|
3598
3631
|
const coverageRangesByInterval = /* @__PURE__ */ new Map();
|
|
3632
|
+
const liquidationCoverageRangesByInterval = /* @__PURE__ */ new Map();
|
|
3633
|
+
const coverageNowMs = Date.now();
|
|
3599
3634
|
await Promise.all(
|
|
3600
3635
|
intervalWindows.map(async (window2) => {
|
|
3601
|
-
const
|
|
3602
|
-
source: "coinalyze",
|
|
3603
|
-
symbols,
|
|
3636
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3604
3637
|
interval: window2.interval,
|
|
3605
3638
|
fromMs: window2.fromMs,
|
|
3606
|
-
toMs: window2.toMs
|
|
3639
|
+
toMs: window2.toMs,
|
|
3640
|
+
nowMs: coverageNowMs
|
|
3607
3641
|
});
|
|
3642
|
+
const [coverageRows, liquidationCoverageRows] = await Promise.all([
|
|
3643
|
+
(0, import_timescale2.getDerivativesBackfillCoverage)({
|
|
3644
|
+
source: "coinalyze",
|
|
3645
|
+
symbols,
|
|
3646
|
+
interval: window2.interval,
|
|
3647
|
+
fromMs: window2.fromMs,
|
|
3648
|
+
toMs: window2.toMs
|
|
3649
|
+
}),
|
|
3650
|
+
confirmedLiquidationWindow ? (0, import_timescale2.getDerivativesMetricCoverage)({
|
|
3651
|
+
source: "coinalyze",
|
|
3652
|
+
metric: "liquidation",
|
|
3653
|
+
symbols,
|
|
3654
|
+
interval: window2.interval,
|
|
3655
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3656
|
+
toMs: confirmedLiquidationWindow.toMs
|
|
3657
|
+
}) : Promise.resolve([])
|
|
3658
|
+
]);
|
|
3608
3659
|
coverageKeysByInterval.set(
|
|
3609
3660
|
window2.interval,
|
|
3610
3661
|
new Set(
|
|
@@ -3626,6 +3677,17 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3626
3677
|
rangesBySymbol.set(symbol, ranges);
|
|
3627
3678
|
}
|
|
3628
3679
|
coverageRangesByInterval.set(window2.interval, rangesBySymbol);
|
|
3680
|
+
const liquidationRangesBySymbol = /* @__PURE__ */ new Map();
|
|
3681
|
+
for (const row of liquidationCoverageRows) {
|
|
3682
|
+
const symbol = row.symbol.toUpperCase();
|
|
3683
|
+
const ranges = liquidationRangesBySymbol.get(symbol) ?? [];
|
|
3684
|
+
ranges.push({ fromMs: row.fromMs, toMs: row.toMs });
|
|
3685
|
+
liquidationRangesBySymbol.set(symbol, ranges);
|
|
3686
|
+
}
|
|
3687
|
+
liquidationCoverageRangesByInterval.set(
|
|
3688
|
+
window2.interval,
|
|
3689
|
+
liquidationRangesBySymbol
|
|
3690
|
+
);
|
|
3629
3691
|
})
|
|
3630
3692
|
);
|
|
3631
3693
|
const cachedWindows = intervalWindows.reduce(
|
|
@@ -3650,7 +3712,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3650
3712
|
(symbol) => backfillWindows.every((backfillWindow) => {
|
|
3651
3713
|
const normalizedSymbol = symbol.toUpperCase();
|
|
3652
3714
|
const coverageRanges = coverageRangesByInterval.get(window2.interval)?.get(normalizedSymbol) ?? [];
|
|
3653
|
-
|
|
3715
|
+
const dataCovered = hasDerivativesWindowCoverage({
|
|
3654
3716
|
edges: edgesBySymbol?.get(normalizedSymbol),
|
|
3655
3717
|
fromMs: backfillWindow.fromMs,
|
|
3656
3718
|
toMs: backfillWindow.toMs
|
|
@@ -3667,6 +3729,19 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3667
3729
|
toMs: backfillWindow.toMs
|
|
3668
3730
|
})
|
|
3669
3731
|
);
|
|
3732
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3733
|
+
interval: window2.interval,
|
|
3734
|
+
fromMs: backfillWindow.fromMs,
|
|
3735
|
+
toMs: backfillWindow.toMs,
|
|
3736
|
+
nowMs: coverageNowMs
|
|
3737
|
+
});
|
|
3738
|
+
const liquidationCovered = confirmedLiquidationWindow == null || resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
3739
|
+
ranges: liquidationCoverageRangesByInterval.get(window2.interval)?.get(normalizedSymbol) ?? [],
|
|
3740
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3741
|
+
toMs: confirmedLiquidationWindow.toMs,
|
|
3742
|
+
intervalMs: window2.intervalMs
|
|
3743
|
+
}) == null;
|
|
3744
|
+
return dataCovered && liquidationCovered;
|
|
3670
3745
|
})
|
|
3671
3746
|
);
|
|
3672
3747
|
});
|
|
@@ -3751,6 +3826,11 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3751
3826
|
coverageKeysByInterval.set(interval, coverageKeys);
|
|
3752
3827
|
const coverageRangesBySymbol = coverageRangesByInterval.get(interval) ?? /* @__PURE__ */ new Map();
|
|
3753
3828
|
coverageRangesByInterval.set(interval, coverageRangesBySymbol);
|
|
3829
|
+
const liquidationCoverageRangesBySymbol = liquidationCoverageRangesByInterval.get(interval) ?? /* @__PURE__ */ new Map();
|
|
3830
|
+
liquidationCoverageRangesByInterval.set(
|
|
3831
|
+
interval,
|
|
3832
|
+
liquidationCoverageRangesBySymbol
|
|
3833
|
+
);
|
|
3754
3834
|
for (let batchIdx = 0; batchIdx < symbolBatches.length; batchIdx += 1) {
|
|
3755
3835
|
const batch = symbolBatches[batchIdx];
|
|
3756
3836
|
let cursor = window2.fromMs;
|
|
@@ -3763,33 +3843,25 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3763
3843
|
fromMs: cursor,
|
|
3764
3844
|
toMs
|
|
3765
3845
|
});
|
|
3766
|
-
if (coverageKeys.has(key)) {
|
|
3767
|
-
return null;
|
|
3768
|
-
}
|
|
3769
3846
|
const normalizedSymbol = item.symbol.toUpperCase();
|
|
3770
|
-
const
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
refreshClosedTail: mode === "signals"
|
|
3786
|
-
});
|
|
3787
|
-
if (edgesFromMs == null) {
|
|
3788
|
-
return null;
|
|
3789
|
-
}
|
|
3847
|
+
const requiredFromMs = resolveDerivativesContextRequiredFetchFromMs(
|
|
3848
|
+
{
|
|
3849
|
+
mode,
|
|
3850
|
+
interval,
|
|
3851
|
+
intervalMs,
|
|
3852
|
+
fromMs: cursor,
|
|
3853
|
+
toMs,
|
|
3854
|
+
nowMs: coverageNowMs,
|
|
3855
|
+
dataCoverageKeyExists: coverageKeys.has(key),
|
|
3856
|
+
dataCoverageRanges: coverageRangesBySymbol.get(normalizedSymbol),
|
|
3857
|
+
liquidationCoverageRanges: liquidationCoverageRangesBySymbol.get(normalizedSymbol),
|
|
3858
|
+
edges: edgesBySymbol.get(normalizedSymbol)
|
|
3859
|
+
}
|
|
3860
|
+
);
|
|
3861
|
+
if (requiredFromMs == null) return null;
|
|
3790
3862
|
return {
|
|
3791
3863
|
item,
|
|
3792
|
-
fromMs:
|
|
3864
|
+
fromMs: requiredFromMs
|
|
3793
3865
|
};
|
|
3794
3866
|
}).filter(
|
|
3795
3867
|
(item) => item != null
|
|
@@ -3814,6 +3886,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3814
3886
|
);
|
|
3815
3887
|
let rows = [];
|
|
3816
3888
|
let missingClosedSymbols = [];
|
|
3889
|
+
let liquidationRowsByMarket = /* @__PURE__ */ new Map();
|
|
3817
3890
|
for (let attempt = 1; attempt <= maxClosedBarAttempts; attempt += 1) {
|
|
3818
3891
|
const oiMap = await fetchMetricBatch({
|
|
3819
3892
|
endpoint: oiPath,
|
|
@@ -3833,7 +3906,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3833
3906
|
fromMs: group.fromMs,
|
|
3834
3907
|
toMs
|
|
3835
3908
|
});
|
|
3836
|
-
|
|
3909
|
+
liquidationRowsByMarket = await fetchMetricBatch({
|
|
3837
3910
|
endpoint: liqPath,
|
|
3838
3911
|
metric: "liq",
|
|
3839
3912
|
marketSymbols,
|
|
@@ -3848,7 +3921,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3848
3921
|
symbol: item.symbol,
|
|
3849
3922
|
oiRaw: oiMap.get(marketSymbol) ?? [],
|
|
3850
3923
|
fundingRaw: fundingMap.get(marketSymbol) ?? [],
|
|
3851
|
-
liqRaw:
|
|
3924
|
+
liqRaw: liquidationRowsByMarket.get(marketSymbol) ?? []
|
|
3852
3925
|
});
|
|
3853
3926
|
return (0, import_indicators.coinalyzePointsToRows)(points, interval, "coinalyze");
|
|
3854
3927
|
});
|
|
@@ -3871,6 +3944,42 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3871
3944
|
await (0, import_timescale2.upsertDerivatives)(rows);
|
|
3872
3945
|
totalRows += rows.length;
|
|
3873
3946
|
}
|
|
3947
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3948
|
+
interval,
|
|
3949
|
+
fromMs: group.fromMs,
|
|
3950
|
+
toMs,
|
|
3951
|
+
nowMs: coverageNowMs
|
|
3952
|
+
});
|
|
3953
|
+
if (confirmedLiquidationWindow) {
|
|
3954
|
+
const metricCoverageRows = missingBatch.map((item) => {
|
|
3955
|
+
const marketSymbol = item.marketSymbol.toUpperCase();
|
|
3956
|
+
const eventRowsCount = (liquidationRowsByMarket.get(marketSymbol) ?? []).filter((point) => {
|
|
3957
|
+
const timestamp = (0, import_indicators.toCoinalyzeTimestampMs)(
|
|
3958
|
+
point.t ?? point.ts ?? point.time ?? point.timestamp
|
|
3959
|
+
);
|
|
3960
|
+
return timestamp != null && timestamp >= confirmedLiquidationWindow.fromMs && timestamp <= confirmedLiquidationWindow.toMs;
|
|
3961
|
+
}).length;
|
|
3962
|
+
return {
|
|
3963
|
+
source: "coinalyze",
|
|
3964
|
+
metric: "liquidation",
|
|
3965
|
+
symbol: item.symbol,
|
|
3966
|
+
interval,
|
|
3967
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3968
|
+
toMs: confirmedLiquidationWindow.toMs,
|
|
3969
|
+
eventRowsCount
|
|
3970
|
+
};
|
|
3971
|
+
});
|
|
3972
|
+
await (0, import_timescale2.applyDerivativesMetricCoverage)(metricCoverageRows);
|
|
3973
|
+
for (const coverageRow of metricCoverageRows) {
|
|
3974
|
+
const symbol = coverageRow.symbol.toUpperCase();
|
|
3975
|
+
const ranges = liquidationCoverageRangesBySymbol.get(symbol) ?? [];
|
|
3976
|
+
ranges.push({
|
|
3977
|
+
fromMs: coverageRow.fromMs,
|
|
3978
|
+
toMs: coverageRow.toMs
|
|
3979
|
+
});
|
|
3980
|
+
liquidationCoverageRangesBySymbol.set(symbol, ranges);
|
|
3981
|
+
}
|
|
3982
|
+
}
|
|
3874
3983
|
if (mode === "backtest") {
|
|
3875
3984
|
const rowsCountBySymbol = /* @__PURE__ */ new Map();
|
|
3876
3985
|
for (const row of rows) {
|
|
@@ -3232,6 +3232,38 @@ var resolveDerivativesContextMissingFetchFromMs = (params) => {
|
|
|
3232
3232
|
return null;
|
|
3233
3233
|
};
|
|
3234
3234
|
var resolveDerivativesContextFetchFromMs = (params) => resolveDerivativesContextMissingFetchFromMs(params) ?? (params.refreshClosedTail ? params.toMs : null);
|
|
3235
|
+
var resolveDerivativesContextRequiredFetchFromMs = (params) => {
|
|
3236
|
+
const dataCoverageFromMs = params.dataCoverageKeyExists ? null : params.mode === "signals" ? params.fromMs : resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
3237
|
+
ranges: params.dataCoverageRanges,
|
|
3238
|
+
fromMs: params.fromMs,
|
|
3239
|
+
toMs: params.toMs,
|
|
3240
|
+
intervalMs: params.intervalMs
|
|
3241
|
+
});
|
|
3242
|
+
const edgesFromMs = dataCoverageFromMs == null ? null : resolveDerivativesContextFetchFromMs({
|
|
3243
|
+
edges: params.edges,
|
|
3244
|
+
fromMs: params.fromMs,
|
|
3245
|
+
toMs: params.toMs,
|
|
3246
|
+
intervalMs: params.intervalMs,
|
|
3247
|
+
refreshClosedTail: params.mode === "signals"
|
|
3248
|
+
});
|
|
3249
|
+
const dataFetchFromMs = dataCoverageFromMs != null && edgesFromMs != null ? Math.max(dataCoverageFromMs, edgesFromMs) : null;
|
|
3250
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3251
|
+
interval: params.interval,
|
|
3252
|
+
fromMs: params.fromMs,
|
|
3253
|
+
toMs: params.toMs,
|
|
3254
|
+
nowMs: params.nowMs
|
|
3255
|
+
});
|
|
3256
|
+
const liquidationFetchFromMs = confirmedLiquidationWindow ? resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
3257
|
+
ranges: params.liquidationCoverageRanges,
|
|
3258
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3259
|
+
toMs: confirmedLiquidationWindow.toMs,
|
|
3260
|
+
intervalMs: params.intervalMs
|
|
3261
|
+
}) : null;
|
|
3262
|
+
const fetchStarts = [dataFetchFromMs, liquidationFetchFromMs].filter(
|
|
3263
|
+
(value) => value != null
|
|
3264
|
+
);
|
|
3265
|
+
return fetchStarts.length ? Math.min(...fetchStarts) : null;
|
|
3266
|
+
};
|
|
3235
3267
|
var countBackfillWindows = (params) => {
|
|
3236
3268
|
let count = 0;
|
|
3237
3269
|
let cursor = params.fromMs;
|
|
@@ -3567,7 +3599,8 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3567
3599
|
mode,
|
|
3568
3600
|
startMs,
|
|
3569
3601
|
endMs,
|
|
3570
|
-
preloadStartMs: params.preloadStartMs
|
|
3602
|
+
preloadStartMs: params.preloadStartMs,
|
|
3603
|
+
nowMs: Date.now()
|
|
3571
3604
|
});
|
|
3572
3605
|
if (safeEndMs <= fromMs) {
|
|
3573
3606
|
return skippedBackfillResult2();
|
|
@@ -3601,15 +3634,33 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3601
3634
|
);
|
|
3602
3635
|
const coverageKeysByInterval = /* @__PURE__ */ new Map();
|
|
3603
3636
|
const coverageRangesByInterval = /* @__PURE__ */ new Map();
|
|
3637
|
+
const liquidationCoverageRangesByInterval = /* @__PURE__ */ new Map();
|
|
3638
|
+
const coverageNowMs = Date.now();
|
|
3604
3639
|
await Promise.all(
|
|
3605
3640
|
intervalWindows.map(async (window2) => {
|
|
3606
|
-
const
|
|
3607
|
-
source: "coinalyze",
|
|
3608
|
-
symbols,
|
|
3641
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3609
3642
|
interval: window2.interval,
|
|
3610
3643
|
fromMs: window2.fromMs,
|
|
3611
|
-
toMs: window2.toMs
|
|
3644
|
+
toMs: window2.toMs,
|
|
3645
|
+
nowMs: coverageNowMs
|
|
3612
3646
|
});
|
|
3647
|
+
const [coverageRows, liquidationCoverageRows] = await Promise.all([
|
|
3648
|
+
(0, import_timescale2.getDerivativesBackfillCoverage)({
|
|
3649
|
+
source: "coinalyze",
|
|
3650
|
+
symbols,
|
|
3651
|
+
interval: window2.interval,
|
|
3652
|
+
fromMs: window2.fromMs,
|
|
3653
|
+
toMs: window2.toMs
|
|
3654
|
+
}),
|
|
3655
|
+
confirmedLiquidationWindow ? (0, import_timescale2.getDerivativesMetricCoverage)({
|
|
3656
|
+
source: "coinalyze",
|
|
3657
|
+
metric: "liquidation",
|
|
3658
|
+
symbols,
|
|
3659
|
+
interval: window2.interval,
|
|
3660
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3661
|
+
toMs: confirmedLiquidationWindow.toMs
|
|
3662
|
+
}) : Promise.resolve([])
|
|
3663
|
+
]);
|
|
3613
3664
|
coverageKeysByInterval.set(
|
|
3614
3665
|
window2.interval,
|
|
3615
3666
|
new Set(
|
|
@@ -3631,6 +3682,17 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3631
3682
|
rangesBySymbol.set(symbol, ranges);
|
|
3632
3683
|
}
|
|
3633
3684
|
coverageRangesByInterval.set(window2.interval, rangesBySymbol);
|
|
3685
|
+
const liquidationRangesBySymbol = /* @__PURE__ */ new Map();
|
|
3686
|
+
for (const row of liquidationCoverageRows) {
|
|
3687
|
+
const symbol = row.symbol.toUpperCase();
|
|
3688
|
+
const ranges = liquidationRangesBySymbol.get(symbol) ?? [];
|
|
3689
|
+
ranges.push({ fromMs: row.fromMs, toMs: row.toMs });
|
|
3690
|
+
liquidationRangesBySymbol.set(symbol, ranges);
|
|
3691
|
+
}
|
|
3692
|
+
liquidationCoverageRangesByInterval.set(
|
|
3693
|
+
window2.interval,
|
|
3694
|
+
liquidationRangesBySymbol
|
|
3695
|
+
);
|
|
3634
3696
|
})
|
|
3635
3697
|
);
|
|
3636
3698
|
const cachedWindows = intervalWindows.reduce(
|
|
@@ -3655,7 +3717,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3655
3717
|
(symbol) => backfillWindows.every((backfillWindow) => {
|
|
3656
3718
|
const normalizedSymbol = symbol.toUpperCase();
|
|
3657
3719
|
const coverageRanges = coverageRangesByInterval.get(window2.interval)?.get(normalizedSymbol) ?? [];
|
|
3658
|
-
|
|
3720
|
+
const dataCovered = hasDerivativesWindowCoverage({
|
|
3659
3721
|
edges: edgesBySymbol?.get(normalizedSymbol),
|
|
3660
3722
|
fromMs: backfillWindow.fromMs,
|
|
3661
3723
|
toMs: backfillWindow.toMs
|
|
@@ -3672,6 +3734,19 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3672
3734
|
toMs: backfillWindow.toMs
|
|
3673
3735
|
})
|
|
3674
3736
|
);
|
|
3737
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3738
|
+
interval: window2.interval,
|
|
3739
|
+
fromMs: backfillWindow.fromMs,
|
|
3740
|
+
toMs: backfillWindow.toMs,
|
|
3741
|
+
nowMs: coverageNowMs
|
|
3742
|
+
});
|
|
3743
|
+
const liquidationCovered = confirmedLiquidationWindow == null || resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
3744
|
+
ranges: liquidationCoverageRangesByInterval.get(window2.interval)?.get(normalizedSymbol) ?? [],
|
|
3745
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3746
|
+
toMs: confirmedLiquidationWindow.toMs,
|
|
3747
|
+
intervalMs: window2.intervalMs
|
|
3748
|
+
}) == null;
|
|
3749
|
+
return dataCovered && liquidationCovered;
|
|
3675
3750
|
})
|
|
3676
3751
|
);
|
|
3677
3752
|
});
|
|
@@ -3756,6 +3831,11 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3756
3831
|
coverageKeysByInterval.set(interval2, coverageKeys);
|
|
3757
3832
|
const coverageRangesBySymbol = coverageRangesByInterval.get(interval2) ?? /* @__PURE__ */ new Map();
|
|
3758
3833
|
coverageRangesByInterval.set(interval2, coverageRangesBySymbol);
|
|
3834
|
+
const liquidationCoverageRangesBySymbol = liquidationCoverageRangesByInterval.get(interval2) ?? /* @__PURE__ */ new Map();
|
|
3835
|
+
liquidationCoverageRangesByInterval.set(
|
|
3836
|
+
interval2,
|
|
3837
|
+
liquidationCoverageRangesBySymbol
|
|
3838
|
+
);
|
|
3759
3839
|
for (let batchIdx = 0; batchIdx < symbolBatches.length; batchIdx += 1) {
|
|
3760
3840
|
const batch = symbolBatches[batchIdx];
|
|
3761
3841
|
let cursor = window2.fromMs;
|
|
@@ -3768,33 +3848,25 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3768
3848
|
fromMs: cursor,
|
|
3769
3849
|
toMs
|
|
3770
3850
|
});
|
|
3771
|
-
if (coverageKeys.has(key)) {
|
|
3772
|
-
return null;
|
|
3773
|
-
}
|
|
3774
3851
|
const normalizedSymbol = item.symbol.toUpperCase();
|
|
3775
|
-
const
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
refreshClosedTail: mode === "signals"
|
|
3791
|
-
});
|
|
3792
|
-
if (edgesFromMs == null) {
|
|
3793
|
-
return null;
|
|
3794
|
-
}
|
|
3852
|
+
const requiredFromMs = resolveDerivativesContextRequiredFetchFromMs(
|
|
3853
|
+
{
|
|
3854
|
+
mode,
|
|
3855
|
+
interval: interval2,
|
|
3856
|
+
intervalMs,
|
|
3857
|
+
fromMs: cursor,
|
|
3858
|
+
toMs,
|
|
3859
|
+
nowMs: coverageNowMs,
|
|
3860
|
+
dataCoverageKeyExists: coverageKeys.has(key),
|
|
3861
|
+
dataCoverageRanges: coverageRangesBySymbol.get(normalizedSymbol),
|
|
3862
|
+
liquidationCoverageRanges: liquidationCoverageRangesBySymbol.get(normalizedSymbol),
|
|
3863
|
+
edges: edgesBySymbol.get(normalizedSymbol)
|
|
3864
|
+
}
|
|
3865
|
+
);
|
|
3866
|
+
if (requiredFromMs == null) return null;
|
|
3795
3867
|
return {
|
|
3796
3868
|
item,
|
|
3797
|
-
fromMs:
|
|
3869
|
+
fromMs: requiredFromMs
|
|
3798
3870
|
};
|
|
3799
3871
|
}).filter(
|
|
3800
3872
|
(item) => item != null
|
|
@@ -3819,6 +3891,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3819
3891
|
);
|
|
3820
3892
|
let rows = [];
|
|
3821
3893
|
let missingClosedSymbols = [];
|
|
3894
|
+
let liquidationRowsByMarket = /* @__PURE__ */ new Map();
|
|
3822
3895
|
for (let attempt = 1; attempt <= maxClosedBarAttempts; attempt += 1) {
|
|
3823
3896
|
const oiMap = await fetchMetricBatch({
|
|
3824
3897
|
endpoint: oiPath,
|
|
@@ -3838,7 +3911,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3838
3911
|
fromMs: group.fromMs,
|
|
3839
3912
|
toMs
|
|
3840
3913
|
});
|
|
3841
|
-
|
|
3914
|
+
liquidationRowsByMarket = await fetchMetricBatch({
|
|
3842
3915
|
endpoint: liqPath,
|
|
3843
3916
|
metric: "liq",
|
|
3844
3917
|
marketSymbols,
|
|
@@ -3853,7 +3926,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3853
3926
|
symbol: item.symbol,
|
|
3854
3927
|
oiRaw: oiMap.get(marketSymbol) ?? [],
|
|
3855
3928
|
fundingRaw: fundingMap.get(marketSymbol) ?? [],
|
|
3856
|
-
liqRaw:
|
|
3929
|
+
liqRaw: liquidationRowsByMarket.get(marketSymbol) ?? []
|
|
3857
3930
|
});
|
|
3858
3931
|
return (0, import_indicators.coinalyzePointsToRows)(points, interval2, "coinalyze");
|
|
3859
3932
|
});
|
|
@@ -3876,6 +3949,42 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3876
3949
|
await (0, import_timescale2.upsertDerivatives)(rows);
|
|
3877
3950
|
totalRows += rows.length;
|
|
3878
3951
|
}
|
|
3952
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3953
|
+
interval: interval2,
|
|
3954
|
+
fromMs: group.fromMs,
|
|
3955
|
+
toMs,
|
|
3956
|
+
nowMs: coverageNowMs
|
|
3957
|
+
});
|
|
3958
|
+
if (confirmedLiquidationWindow) {
|
|
3959
|
+
const metricCoverageRows = missingBatch.map((item) => {
|
|
3960
|
+
const marketSymbol = item.marketSymbol.toUpperCase();
|
|
3961
|
+
const eventRowsCount = (liquidationRowsByMarket.get(marketSymbol) ?? []).filter((point) => {
|
|
3962
|
+
const timestamp = (0, import_indicators.toCoinalyzeTimestampMs)(
|
|
3963
|
+
point.t ?? point.ts ?? point.time ?? point.timestamp
|
|
3964
|
+
);
|
|
3965
|
+
return timestamp != null && timestamp >= confirmedLiquidationWindow.fromMs && timestamp <= confirmedLiquidationWindow.toMs;
|
|
3966
|
+
}).length;
|
|
3967
|
+
return {
|
|
3968
|
+
source: "coinalyze",
|
|
3969
|
+
metric: "liquidation",
|
|
3970
|
+
symbol: item.symbol,
|
|
3971
|
+
interval: interval2,
|
|
3972
|
+
fromMs: confirmedLiquidationWindow.fromMs,
|
|
3973
|
+
toMs: confirmedLiquidationWindow.toMs,
|
|
3974
|
+
eventRowsCount
|
|
3975
|
+
};
|
|
3976
|
+
});
|
|
3977
|
+
await (0, import_timescale2.applyDerivativesMetricCoverage)(metricCoverageRows);
|
|
3978
|
+
for (const coverageRow of metricCoverageRows) {
|
|
3979
|
+
const symbol = coverageRow.symbol.toUpperCase();
|
|
3980
|
+
const ranges = liquidationCoverageRangesBySymbol.get(symbol) ?? [];
|
|
3981
|
+
ranges.push({
|
|
3982
|
+
fromMs: coverageRow.fromMs,
|
|
3983
|
+
toMs: coverageRow.toMs
|
|
3984
|
+
});
|
|
3985
|
+
liquidationCoverageRangesBySymbol.set(symbol, ranges);
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3879
3988
|
if (mode === "backtest") {
|
|
3880
3989
|
const rowsCountBySymbol = /* @__PURE__ */ new Map();
|
|
3881
3990
|
for (const row of rows) {
|