@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
|
@@ -3109,7 +3109,7 @@ var import_userSettings = require("@tradejs/infra/userSettings");
|
|
|
3109
3109
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
3110
3110
|
var DAY_MS2 = 24 * HOUR_MS;
|
|
3111
3111
|
var DEFAULT_LOOKBACK_HOURS = 48;
|
|
3112
|
-
var
|
|
3112
|
+
var SOURCE_INTERVALS = ["15m"];
|
|
3113
3113
|
var coinalyzeIntervalMap = {
|
|
3114
3114
|
"15m": "15min",
|
|
3115
3115
|
"1h": "1hour"
|
|
@@ -3170,10 +3170,7 @@ var isDerivativesContextBackfillEnabled = (env) => {
|
|
|
3170
3170
|
var shouldBackfillDerivativesContextForBacktest = (params) => !params.cacheOnly && (params.aiEnabled || params.mlEnabled) && isBacktestDerivativesContextEnabled();
|
|
3171
3171
|
var shouldBackfillDerivativesContextForSignals = (params) => !params.cacheOnly && isSignalsDerivativesContextEnabled();
|
|
3172
3172
|
var resolveDerivativesContextIntervals = () => {
|
|
3173
|
-
|
|
3174
|
-
process.env.DERIVATIVES_CONTEXT_INTERVALS
|
|
3175
|
-
);
|
|
3176
|
-
return intervals.length ? intervals : DEFAULT_INTERVALS;
|
|
3173
|
+
return [...SOURCE_INTERVALS];
|
|
3177
3174
|
};
|
|
3178
3175
|
var resolveDerivativesContextLookbackMs = () => {
|
|
3179
3176
|
const hours = Number(process.env.DERIVATIVES_CONTEXT_LOOKBACK_HOURS);
|
|
@@ -3208,9 +3205,10 @@ var resolveDerivativesContextBackfillWindow = (params) => {
|
|
|
3208
3205
|
};
|
|
3209
3206
|
var resolveDerivativesContextIntervalBackfillWindow = (params) => {
|
|
3210
3207
|
const intervalMs = derivativesIntervalMs(params.interval);
|
|
3208
|
+
const alignedToMs = params.closedOnly ? (0, import_indicators.getLastClosedDerivativesBarStartMs)(params.toMs, params.interval) : Math.floor(params.toMs / intervalMs) * intervalMs;
|
|
3211
3209
|
return {
|
|
3212
3210
|
fromMs: Math.floor(params.fromMs / intervalMs) * intervalMs,
|
|
3213
|
-
toMs:
|
|
3211
|
+
toMs: alignedToMs,
|
|
3214
3212
|
intervalMs
|
|
3215
3213
|
};
|
|
3216
3214
|
};
|
|
@@ -3228,6 +3226,39 @@ var resolveDerivativesContextMissingFetchFromMs = (params) => {
|
|
|
3228
3226
|
}
|
|
3229
3227
|
return null;
|
|
3230
3228
|
};
|
|
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
|
+
};
|
|
3231
3262
|
var countBackfillWindows = (params) => {
|
|
3232
3263
|
let count = 0;
|
|
3233
3264
|
let cursor = params.fromMs;
|
|
@@ -3291,6 +3322,14 @@ var groupDerivativesContextMissingFetchRanges = (ranges) => {
|
|
|
3291
3322
|
}
|
|
3292
3323
|
return [...groups.entries()].sort(([a], [b]) => a - b).map(([fromMs, items]) => ({ fromMs, items }));
|
|
3293
3324
|
};
|
|
3325
|
+
var getMissingClosedDerivativesSymbols = (params) => {
|
|
3326
|
+
const availableSymbols = new Set(
|
|
3327
|
+
params.rows.filter((row) => row.ts.getTime() === params.expectedTimestamp).map((row) => row.symbol.trim().toUpperCase())
|
|
3328
|
+
);
|
|
3329
|
+
return params.symbols.filter(
|
|
3330
|
+
(symbol) => !availableSymbols.has(symbol.trim().toUpperCase())
|
|
3331
|
+
);
|
|
3332
|
+
};
|
|
3294
3333
|
var coverageKey = (params) => [
|
|
3295
3334
|
params.symbol.trim().toUpperCase(),
|
|
3296
3335
|
params.interval,
|
|
@@ -3555,7 +3594,8 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3555
3594
|
mode,
|
|
3556
3595
|
startMs,
|
|
3557
3596
|
endMs,
|
|
3558
|
-
preloadStartMs: params.preloadStartMs
|
|
3597
|
+
preloadStartMs: params.preloadStartMs,
|
|
3598
|
+
nowMs: Date.now()
|
|
3559
3599
|
});
|
|
3560
3600
|
if (safeEndMs <= fromMs) {
|
|
3561
3601
|
return skippedBackfillResult2();
|
|
@@ -3570,7 +3610,8 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3570
3610
|
...resolveDerivativesContextIntervalBackfillWindow({
|
|
3571
3611
|
fromMs,
|
|
3572
3612
|
toMs: safeEndMs,
|
|
3573
|
-
interval
|
|
3613
|
+
interval,
|
|
3614
|
+
closedOnly: mode === "signals"
|
|
3574
3615
|
})
|
|
3575
3616
|
})).filter((item) => item.toMs > item.fromMs);
|
|
3576
3617
|
if (!intervalWindows.length) {
|
|
@@ -3588,15 +3629,33 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3588
3629
|
);
|
|
3589
3630
|
const coverageKeysByInterval = /* @__PURE__ */ new Map();
|
|
3590
3631
|
const coverageRangesByInterval = /* @__PURE__ */ new Map();
|
|
3632
|
+
const liquidationCoverageRangesByInterval = /* @__PURE__ */ new Map();
|
|
3633
|
+
const coverageNowMs = Date.now();
|
|
3591
3634
|
await Promise.all(
|
|
3592
3635
|
intervalWindows.map(async (window2) => {
|
|
3593
|
-
const
|
|
3594
|
-
source: "coinalyze",
|
|
3595
|
-
symbols,
|
|
3636
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3596
3637
|
interval: window2.interval,
|
|
3597
3638
|
fromMs: window2.fromMs,
|
|
3598
|
-
toMs: window2.toMs
|
|
3639
|
+
toMs: window2.toMs,
|
|
3640
|
+
nowMs: coverageNowMs
|
|
3599
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
|
+
]);
|
|
3600
3659
|
coverageKeysByInterval.set(
|
|
3601
3660
|
window2.interval,
|
|
3602
3661
|
new Set(
|
|
@@ -3618,6 +3677,17 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3618
3677
|
rangesBySymbol.set(symbol, ranges);
|
|
3619
3678
|
}
|
|
3620
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
|
+
);
|
|
3621
3691
|
})
|
|
3622
3692
|
);
|
|
3623
3693
|
const cachedWindows = intervalWindows.reduce(
|
|
@@ -3629,7 +3699,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3629
3699
|
}),
|
|
3630
3700
|
0
|
|
3631
3701
|
);
|
|
3632
|
-
const allBackfillWindowsCached = intervalWindows.every((window2) => {
|
|
3702
|
+
const allBackfillWindowsCached = mode !== "signals" && intervalWindows.every((window2) => {
|
|
3633
3703
|
const edgesBySymbol = edgesByInterval.get(window2.interval);
|
|
3634
3704
|
const coverageKeys = coverageKeysByInterval.get(window2.interval);
|
|
3635
3705
|
const backfillWindows = buildBackfillWindows({
|
|
@@ -3642,7 +3712,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3642
3712
|
(symbol) => backfillWindows.every((backfillWindow) => {
|
|
3643
3713
|
const normalizedSymbol = symbol.toUpperCase();
|
|
3644
3714
|
const coverageRanges = coverageRangesByInterval.get(window2.interval)?.get(normalizedSymbol) ?? [];
|
|
3645
|
-
|
|
3715
|
+
const dataCovered = hasDerivativesWindowCoverage({
|
|
3646
3716
|
edges: edgesBySymbol?.get(normalizedSymbol),
|
|
3647
3717
|
fromMs: backfillWindow.fromMs,
|
|
3648
3718
|
toMs: backfillWindow.toMs
|
|
@@ -3659,6 +3729,19 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3659
3729
|
toMs: backfillWindow.toMs
|
|
3660
3730
|
})
|
|
3661
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;
|
|
3662
3745
|
})
|
|
3663
3746
|
);
|
|
3664
3747
|
});
|
|
@@ -3743,6 +3826,11 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3743
3826
|
coverageKeysByInterval.set(interval, coverageKeys);
|
|
3744
3827
|
const coverageRangesBySymbol = coverageRangesByInterval.get(interval) ?? /* @__PURE__ */ new Map();
|
|
3745
3828
|
coverageRangesByInterval.set(interval, coverageRangesBySymbol);
|
|
3829
|
+
const liquidationCoverageRangesBySymbol = liquidationCoverageRangesByInterval.get(interval) ?? /* @__PURE__ */ new Map();
|
|
3830
|
+
liquidationCoverageRangesByInterval.set(
|
|
3831
|
+
interval,
|
|
3832
|
+
liquidationCoverageRangesBySymbol
|
|
3833
|
+
);
|
|
3746
3834
|
for (let batchIdx = 0; batchIdx < symbolBatches.length; batchIdx += 1) {
|
|
3747
3835
|
const batch = symbolBatches[batchIdx];
|
|
3748
3836
|
let cursor = window2.fromMs;
|
|
@@ -3755,30 +3843,26 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3755
3843
|
fromMs: cursor,
|
|
3756
3844
|
toMs
|
|
3757
3845
|
});
|
|
3758
|
-
if (coverageKeys.has(key)) {
|
|
3759
|
-
return null;
|
|
3760
|
-
}
|
|
3761
3846
|
const normalizedSymbol = item.symbol.toUpperCase();
|
|
3762
|
-
const
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
}
|
|
3781
|
-
return { item, fromMs: Math.max(coverageFromMs, edgesFromMs) };
|
|
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;
|
|
3862
|
+
return {
|
|
3863
|
+
item,
|
|
3864
|
+
fromMs: requiredFromMs
|
|
3865
|
+
};
|
|
3782
3866
|
}).filter(
|
|
3783
3867
|
(item) => item != null
|
|
3784
3868
|
);
|
|
@@ -3792,85 +3876,150 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3792
3876
|
const marketSymbols = missingBatch.map(
|
|
3793
3877
|
(item) => item.marketSymbol
|
|
3794
3878
|
);
|
|
3795
|
-
const
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
metric: "liq",
|
|
3816
|
-
marketSymbols,
|
|
3817
|
-
apiKey,
|
|
3818
|
-
interval,
|
|
3819
|
-
fromMs: group.fromMs,
|
|
3820
|
-
toMs
|
|
3821
|
-
});
|
|
3822
|
-
const rows = missingBatch.flatMap((item) => {
|
|
3823
|
-
const marketSymbol = item.marketSymbol.toUpperCase();
|
|
3824
|
-
const points = (0, import_indicators.mergeCoinalyzeMetrics)({
|
|
3825
|
-
symbol: item.symbol,
|
|
3826
|
-
oiRaw: oiMap.get(marketSymbol) ?? [],
|
|
3827
|
-
fundingRaw: fundingMap.get(marketSymbol) ?? [],
|
|
3828
|
-
liqRaw: liqMap.get(marketSymbol) ?? []
|
|
3879
|
+
const maxClosedBarAttempts = mode === "signals" ? asInt2(
|
|
3880
|
+
process.env.DERIVATIVES_CONTEXT_CLOSED_BAR_MAX_ATTEMPTS,
|
|
3881
|
+
3
|
|
3882
|
+
) : 1;
|
|
3883
|
+
const closedBarRetryDelayMs = asInt2(
|
|
3884
|
+
process.env.DERIVATIVES_CONTEXT_CLOSED_BAR_RETRY_DELAY_MS,
|
|
3885
|
+
2e3
|
|
3886
|
+
);
|
|
3887
|
+
let rows = [];
|
|
3888
|
+
let missingClosedSymbols = [];
|
|
3889
|
+
let liquidationRowsByMarket = /* @__PURE__ */ new Map();
|
|
3890
|
+
for (let attempt = 1; attempt <= maxClosedBarAttempts; attempt += 1) {
|
|
3891
|
+
const oiMap = await fetchMetricBatch({
|
|
3892
|
+
endpoint: oiPath,
|
|
3893
|
+
metric: "oi",
|
|
3894
|
+
marketSymbols,
|
|
3895
|
+
apiKey,
|
|
3896
|
+
interval,
|
|
3897
|
+
fromMs: group.fromMs,
|
|
3898
|
+
toMs
|
|
3829
3899
|
});
|
|
3830
|
-
|
|
3831
|
-
|
|
3900
|
+
const fundingMap = await fetchMetricBatch({
|
|
3901
|
+
endpoint: fundingPath,
|
|
3902
|
+
metric: "funding",
|
|
3903
|
+
marketSymbols,
|
|
3904
|
+
apiKey,
|
|
3905
|
+
interval,
|
|
3906
|
+
fromMs: group.fromMs,
|
|
3907
|
+
toMs
|
|
3908
|
+
});
|
|
3909
|
+
liquidationRowsByMarket = await fetchMetricBatch({
|
|
3910
|
+
endpoint: liqPath,
|
|
3911
|
+
metric: "liq",
|
|
3912
|
+
marketSymbols,
|
|
3913
|
+
apiKey,
|
|
3914
|
+
interval,
|
|
3915
|
+
fromMs: group.fromMs,
|
|
3916
|
+
toMs
|
|
3917
|
+
});
|
|
3918
|
+
rows = missingBatch.flatMap((item) => {
|
|
3919
|
+
const marketSymbol = item.marketSymbol.toUpperCase();
|
|
3920
|
+
const points = (0, import_indicators.mergeCoinalyzeMetrics)({
|
|
3921
|
+
symbol: item.symbol,
|
|
3922
|
+
oiRaw: oiMap.get(marketSymbol) ?? [],
|
|
3923
|
+
fundingRaw: fundingMap.get(marketSymbol) ?? [],
|
|
3924
|
+
liqRaw: liquidationRowsByMarket.get(marketSymbol) ?? []
|
|
3925
|
+
});
|
|
3926
|
+
return (0, import_indicators.coinalyzePointsToRows)(points, interval, "coinalyze");
|
|
3927
|
+
});
|
|
3928
|
+
missingClosedSymbols = mode === "signals" ? getMissingClosedDerivativesSymbols({
|
|
3929
|
+
symbols: missingBatch.map((item) => item.symbol),
|
|
3930
|
+
rows,
|
|
3931
|
+
expectedTimestamp: toMs
|
|
3932
|
+
}) : [];
|
|
3933
|
+
if (!missingClosedSymbols.length) break;
|
|
3934
|
+
if (attempt < maxClosedBarAttempts) {
|
|
3935
|
+
await (0, import_async.delay)(closedBarRetryDelayMs);
|
|
3936
|
+
}
|
|
3937
|
+
}
|
|
3938
|
+
if (missingClosedSymbols.length) {
|
|
3939
|
+
throw new Error(
|
|
3940
|
+
`Coinalyze closed ${interval} bar ${new Date(toMs).toISOString()} unavailable for ${missingClosedSymbols.join(",")}`
|
|
3941
|
+
);
|
|
3942
|
+
}
|
|
3832
3943
|
if (rows.length) {
|
|
3833
3944
|
await (0, import_timescale2.upsertDerivatives)(rows);
|
|
3834
3945
|
totalRows += rows.length;
|
|
3835
3946
|
}
|
|
3836
|
-
const
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
(rowsCountBySymbol.get(symbol) ?? 0) + 1
|
|
3842
|
-
);
|
|
3843
|
-
}
|
|
3844
|
-
const coverageRows = missingBatch.map((item) => {
|
|
3845
|
-
const normalizedSymbol = item.symbol.toUpperCase();
|
|
3846
|
-
const rowsCount = rowsCountBySymbol.get(normalizedSymbol) ?? 0;
|
|
3847
|
-
return {
|
|
3848
|
-
source: "coinalyze",
|
|
3849
|
-
symbol: item.symbol,
|
|
3850
|
-
interval,
|
|
3851
|
-
fromMs: cursor,
|
|
3852
|
-
toMs,
|
|
3853
|
-
rowsCount
|
|
3854
|
-
};
|
|
3947
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3948
|
+
interval,
|
|
3949
|
+
fromMs: group.fromMs,
|
|
3950
|
+
toMs,
|
|
3951
|
+
nowMs: coverageNowMs
|
|
3855
3952
|
});
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
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
|
+
}
|
|
3983
|
+
if (mode === "backtest") {
|
|
3984
|
+
const rowsCountBySymbol = /* @__PURE__ */ new Map();
|
|
3985
|
+
for (const row of rows) {
|
|
3986
|
+
const symbol = row.symbol.toUpperCase();
|
|
3987
|
+
rowsCountBySymbol.set(
|
|
3865
3988
|
symbol,
|
|
3989
|
+
(rowsCountBySymbol.get(symbol) ?? 0) + 1
|
|
3990
|
+
);
|
|
3991
|
+
}
|
|
3992
|
+
const coverageRows = missingBatch.map((item) => {
|
|
3993
|
+
const normalizedSymbol = item.symbol.toUpperCase();
|
|
3994
|
+
const rowsCount = rowsCountBySymbol.get(normalizedSymbol) ?? 0;
|
|
3995
|
+
return {
|
|
3996
|
+
source: "coinalyze",
|
|
3997
|
+
symbol: item.symbol,
|
|
3866
3998
|
interval,
|
|
3867
3999
|
fromMs: cursor,
|
|
3868
|
-
toMs
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
4000
|
+
toMs,
|
|
4001
|
+
rowsCount
|
|
4002
|
+
};
|
|
4003
|
+
});
|
|
4004
|
+
await (0, import_timescale2.upsertDerivativesBackfillCoverage)(coverageRows);
|
|
4005
|
+
for (const coverageRow of coverageRows) {
|
|
4006
|
+
const symbol = coverageRow.symbol.toUpperCase();
|
|
4007
|
+
edgesBySymbol.set(
|
|
4008
|
+
symbol,
|
|
4009
|
+
extendEdges(edgesBySymbol.get(symbol), cursor, toMs)
|
|
4010
|
+
);
|
|
4011
|
+
coverageKeys.add(
|
|
4012
|
+
coverageKey({
|
|
4013
|
+
symbol,
|
|
4014
|
+
interval,
|
|
4015
|
+
fromMs: cursor,
|
|
4016
|
+
toMs
|
|
4017
|
+
})
|
|
4018
|
+
);
|
|
4019
|
+
const coverageRanges = coverageRangesBySymbol.get(symbol) ?? [];
|
|
4020
|
+
coverageRanges.push({ fromMs: cursor, toMs });
|
|
4021
|
+
coverageRangesBySymbol.set(symbol, coverageRanges);
|
|
4022
|
+
}
|
|
3874
4023
|
}
|
|
3875
4024
|
}
|
|
3876
4025
|
}
|