@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
|
@@ -3114,7 +3114,7 @@ var import_userSettings = require("@tradejs/infra/userSettings");
|
|
|
3114
3114
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
3115
3115
|
var DAY_MS2 = 24 * HOUR_MS;
|
|
3116
3116
|
var DEFAULT_LOOKBACK_HOURS = 48;
|
|
3117
|
-
var
|
|
3117
|
+
var SOURCE_INTERVALS = ["15m"];
|
|
3118
3118
|
var coinalyzeIntervalMap = {
|
|
3119
3119
|
"15m": "15min",
|
|
3120
3120
|
"1h": "1hour"
|
|
@@ -3175,10 +3175,7 @@ var isDerivativesContextBackfillEnabled = (env) => {
|
|
|
3175
3175
|
var shouldBackfillDerivativesContextForBacktest = (params) => !params.cacheOnly && (params.aiEnabled || params.mlEnabled) && isBacktestDerivativesContextEnabled();
|
|
3176
3176
|
var shouldBackfillDerivativesContextForSignals = (params) => !params.cacheOnly && isSignalsDerivativesContextEnabled();
|
|
3177
3177
|
var resolveDerivativesContextIntervals = () => {
|
|
3178
|
-
|
|
3179
|
-
process.env.DERIVATIVES_CONTEXT_INTERVALS
|
|
3180
|
-
);
|
|
3181
|
-
return intervals.length ? intervals : DEFAULT_INTERVALS;
|
|
3178
|
+
return [...SOURCE_INTERVALS];
|
|
3182
3179
|
};
|
|
3183
3180
|
var resolveDerivativesContextLookbackMs = () => {
|
|
3184
3181
|
const hours = Number(process.env.DERIVATIVES_CONTEXT_LOOKBACK_HOURS);
|
|
@@ -3213,9 +3210,10 @@ var resolveDerivativesContextBackfillWindow = (params) => {
|
|
|
3213
3210
|
};
|
|
3214
3211
|
var resolveDerivativesContextIntervalBackfillWindow = (params) => {
|
|
3215
3212
|
const intervalMs = derivativesIntervalMs(params.interval);
|
|
3213
|
+
const alignedToMs = params.closedOnly ? (0, import_indicators.getLastClosedDerivativesBarStartMs)(params.toMs, params.interval) : Math.floor(params.toMs / intervalMs) * intervalMs;
|
|
3216
3214
|
return {
|
|
3217
3215
|
fromMs: Math.floor(params.fromMs / intervalMs) * intervalMs,
|
|
3218
|
-
toMs:
|
|
3216
|
+
toMs: alignedToMs,
|
|
3219
3217
|
intervalMs
|
|
3220
3218
|
};
|
|
3221
3219
|
};
|
|
@@ -3233,6 +3231,39 @@ var resolveDerivativesContextMissingFetchFromMs = (params) => {
|
|
|
3233
3231
|
}
|
|
3234
3232
|
return null;
|
|
3235
3233
|
};
|
|
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
|
+
};
|
|
3236
3267
|
var countBackfillWindows = (params) => {
|
|
3237
3268
|
let count = 0;
|
|
3238
3269
|
let cursor = params.fromMs;
|
|
@@ -3296,6 +3327,14 @@ var groupDerivativesContextMissingFetchRanges = (ranges) => {
|
|
|
3296
3327
|
}
|
|
3297
3328
|
return [...groups.entries()].sort(([a], [b]) => a - b).map(([fromMs, items]) => ({ fromMs, items }));
|
|
3298
3329
|
};
|
|
3330
|
+
var getMissingClosedDerivativesSymbols = (params) => {
|
|
3331
|
+
const availableSymbols = new Set(
|
|
3332
|
+
params.rows.filter((row) => row.ts.getTime() === params.expectedTimestamp).map((row) => row.symbol.trim().toUpperCase())
|
|
3333
|
+
);
|
|
3334
|
+
return params.symbols.filter(
|
|
3335
|
+
(symbol) => !availableSymbols.has(symbol.trim().toUpperCase())
|
|
3336
|
+
);
|
|
3337
|
+
};
|
|
3299
3338
|
var coverageKey = (params) => [
|
|
3300
3339
|
params.symbol.trim().toUpperCase(),
|
|
3301
3340
|
params.interval,
|
|
@@ -3560,7 +3599,8 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3560
3599
|
mode,
|
|
3561
3600
|
startMs,
|
|
3562
3601
|
endMs,
|
|
3563
|
-
preloadStartMs: params.preloadStartMs
|
|
3602
|
+
preloadStartMs: params.preloadStartMs,
|
|
3603
|
+
nowMs: Date.now()
|
|
3564
3604
|
});
|
|
3565
3605
|
if (safeEndMs <= fromMs) {
|
|
3566
3606
|
return skippedBackfillResult2();
|
|
@@ -3575,7 +3615,8 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3575
3615
|
...resolveDerivativesContextIntervalBackfillWindow({
|
|
3576
3616
|
fromMs,
|
|
3577
3617
|
toMs: safeEndMs,
|
|
3578
|
-
interval: interval2
|
|
3618
|
+
interval: interval2,
|
|
3619
|
+
closedOnly: mode === "signals"
|
|
3579
3620
|
})
|
|
3580
3621
|
})).filter((item) => item.toMs > item.fromMs);
|
|
3581
3622
|
if (!intervalWindows.length) {
|
|
@@ -3593,15 +3634,33 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3593
3634
|
);
|
|
3594
3635
|
const coverageKeysByInterval = /* @__PURE__ */ new Map();
|
|
3595
3636
|
const coverageRangesByInterval = /* @__PURE__ */ new Map();
|
|
3637
|
+
const liquidationCoverageRangesByInterval = /* @__PURE__ */ new Map();
|
|
3638
|
+
const coverageNowMs = Date.now();
|
|
3596
3639
|
await Promise.all(
|
|
3597
3640
|
intervalWindows.map(async (window2) => {
|
|
3598
|
-
const
|
|
3599
|
-
source: "coinalyze",
|
|
3600
|
-
symbols,
|
|
3641
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3601
3642
|
interval: window2.interval,
|
|
3602
3643
|
fromMs: window2.fromMs,
|
|
3603
|
-
toMs: window2.toMs
|
|
3644
|
+
toMs: window2.toMs,
|
|
3645
|
+
nowMs: coverageNowMs
|
|
3604
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
|
+
]);
|
|
3605
3664
|
coverageKeysByInterval.set(
|
|
3606
3665
|
window2.interval,
|
|
3607
3666
|
new Set(
|
|
@@ -3623,6 +3682,17 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3623
3682
|
rangesBySymbol.set(symbol, ranges);
|
|
3624
3683
|
}
|
|
3625
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
|
+
);
|
|
3626
3696
|
})
|
|
3627
3697
|
);
|
|
3628
3698
|
const cachedWindows = intervalWindows.reduce(
|
|
@@ -3634,7 +3704,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3634
3704
|
}),
|
|
3635
3705
|
0
|
|
3636
3706
|
);
|
|
3637
|
-
const allBackfillWindowsCached = intervalWindows.every((window2) => {
|
|
3707
|
+
const allBackfillWindowsCached = mode !== "signals" && intervalWindows.every((window2) => {
|
|
3638
3708
|
const edgesBySymbol = edgesByInterval.get(window2.interval);
|
|
3639
3709
|
const coverageKeys = coverageKeysByInterval.get(window2.interval);
|
|
3640
3710
|
const backfillWindows = buildBackfillWindows({
|
|
@@ -3647,7 +3717,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3647
3717
|
(symbol) => backfillWindows.every((backfillWindow) => {
|
|
3648
3718
|
const normalizedSymbol = symbol.toUpperCase();
|
|
3649
3719
|
const coverageRanges = coverageRangesByInterval.get(window2.interval)?.get(normalizedSymbol) ?? [];
|
|
3650
|
-
|
|
3720
|
+
const dataCovered = hasDerivativesWindowCoverage({
|
|
3651
3721
|
edges: edgesBySymbol?.get(normalizedSymbol),
|
|
3652
3722
|
fromMs: backfillWindow.fromMs,
|
|
3653
3723
|
toMs: backfillWindow.toMs
|
|
@@ -3664,6 +3734,19 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3664
3734
|
toMs: backfillWindow.toMs
|
|
3665
3735
|
})
|
|
3666
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;
|
|
3667
3750
|
})
|
|
3668
3751
|
);
|
|
3669
3752
|
});
|
|
@@ -3748,6 +3831,11 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3748
3831
|
coverageKeysByInterval.set(interval2, coverageKeys);
|
|
3749
3832
|
const coverageRangesBySymbol = coverageRangesByInterval.get(interval2) ?? /* @__PURE__ */ new Map();
|
|
3750
3833
|
coverageRangesByInterval.set(interval2, coverageRangesBySymbol);
|
|
3834
|
+
const liquidationCoverageRangesBySymbol = liquidationCoverageRangesByInterval.get(interval2) ?? /* @__PURE__ */ new Map();
|
|
3835
|
+
liquidationCoverageRangesByInterval.set(
|
|
3836
|
+
interval2,
|
|
3837
|
+
liquidationCoverageRangesBySymbol
|
|
3838
|
+
);
|
|
3751
3839
|
for (let batchIdx = 0; batchIdx < symbolBatches.length; batchIdx += 1) {
|
|
3752
3840
|
const batch = symbolBatches[batchIdx];
|
|
3753
3841
|
let cursor = window2.fromMs;
|
|
@@ -3760,30 +3848,26 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3760
3848
|
fromMs: cursor,
|
|
3761
3849
|
toMs
|
|
3762
3850
|
});
|
|
3763
|
-
if (coverageKeys.has(key)) {
|
|
3764
|
-
return null;
|
|
3765
|
-
}
|
|
3766
3851
|
const normalizedSymbol = item.symbol.toUpperCase();
|
|
3767
|
-
const
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
}
|
|
3786
|
-
return { item, fromMs: Math.max(coverageFromMs, edgesFromMs) };
|
|
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;
|
|
3867
|
+
return {
|
|
3868
|
+
item,
|
|
3869
|
+
fromMs: requiredFromMs
|
|
3870
|
+
};
|
|
3787
3871
|
}).filter(
|
|
3788
3872
|
(item) => item != null
|
|
3789
3873
|
);
|
|
@@ -3797,85 +3881,150 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3797
3881
|
const marketSymbols = missingBatch.map(
|
|
3798
3882
|
(item) => item.marketSymbol
|
|
3799
3883
|
);
|
|
3800
|
-
const
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
metric: "liq",
|
|
3821
|
-
marketSymbols,
|
|
3822
|
-
apiKey,
|
|
3823
|
-
interval: interval2,
|
|
3824
|
-
fromMs: group.fromMs,
|
|
3825
|
-
toMs
|
|
3826
|
-
});
|
|
3827
|
-
const rows = missingBatch.flatMap((item) => {
|
|
3828
|
-
const marketSymbol = item.marketSymbol.toUpperCase();
|
|
3829
|
-
const points = (0, import_indicators.mergeCoinalyzeMetrics)({
|
|
3830
|
-
symbol: item.symbol,
|
|
3831
|
-
oiRaw: oiMap.get(marketSymbol) ?? [],
|
|
3832
|
-
fundingRaw: fundingMap.get(marketSymbol) ?? [],
|
|
3833
|
-
liqRaw: liqMap.get(marketSymbol) ?? []
|
|
3884
|
+
const maxClosedBarAttempts = mode === "signals" ? asInt2(
|
|
3885
|
+
process.env.DERIVATIVES_CONTEXT_CLOSED_BAR_MAX_ATTEMPTS,
|
|
3886
|
+
3
|
|
3887
|
+
) : 1;
|
|
3888
|
+
const closedBarRetryDelayMs = asInt2(
|
|
3889
|
+
process.env.DERIVATIVES_CONTEXT_CLOSED_BAR_RETRY_DELAY_MS,
|
|
3890
|
+
2e3
|
|
3891
|
+
);
|
|
3892
|
+
let rows = [];
|
|
3893
|
+
let missingClosedSymbols = [];
|
|
3894
|
+
let liquidationRowsByMarket = /* @__PURE__ */ new Map();
|
|
3895
|
+
for (let attempt = 1; attempt <= maxClosedBarAttempts; attempt += 1) {
|
|
3896
|
+
const oiMap = await fetchMetricBatch({
|
|
3897
|
+
endpoint: oiPath,
|
|
3898
|
+
metric: "oi",
|
|
3899
|
+
marketSymbols,
|
|
3900
|
+
apiKey,
|
|
3901
|
+
interval: interval2,
|
|
3902
|
+
fromMs: group.fromMs,
|
|
3903
|
+
toMs
|
|
3834
3904
|
});
|
|
3835
|
-
|
|
3836
|
-
|
|
3905
|
+
const fundingMap = await fetchMetricBatch({
|
|
3906
|
+
endpoint: fundingPath,
|
|
3907
|
+
metric: "funding",
|
|
3908
|
+
marketSymbols,
|
|
3909
|
+
apiKey,
|
|
3910
|
+
interval: interval2,
|
|
3911
|
+
fromMs: group.fromMs,
|
|
3912
|
+
toMs
|
|
3913
|
+
});
|
|
3914
|
+
liquidationRowsByMarket = await fetchMetricBatch({
|
|
3915
|
+
endpoint: liqPath,
|
|
3916
|
+
metric: "liq",
|
|
3917
|
+
marketSymbols,
|
|
3918
|
+
apiKey,
|
|
3919
|
+
interval: interval2,
|
|
3920
|
+
fromMs: group.fromMs,
|
|
3921
|
+
toMs
|
|
3922
|
+
});
|
|
3923
|
+
rows = missingBatch.flatMap((item) => {
|
|
3924
|
+
const marketSymbol = item.marketSymbol.toUpperCase();
|
|
3925
|
+
const points = (0, import_indicators.mergeCoinalyzeMetrics)({
|
|
3926
|
+
symbol: item.symbol,
|
|
3927
|
+
oiRaw: oiMap.get(marketSymbol) ?? [],
|
|
3928
|
+
fundingRaw: fundingMap.get(marketSymbol) ?? [],
|
|
3929
|
+
liqRaw: liquidationRowsByMarket.get(marketSymbol) ?? []
|
|
3930
|
+
});
|
|
3931
|
+
return (0, import_indicators.coinalyzePointsToRows)(points, interval2, "coinalyze");
|
|
3932
|
+
});
|
|
3933
|
+
missingClosedSymbols = mode === "signals" ? getMissingClosedDerivativesSymbols({
|
|
3934
|
+
symbols: missingBatch.map((item) => item.symbol),
|
|
3935
|
+
rows,
|
|
3936
|
+
expectedTimestamp: toMs
|
|
3937
|
+
}) : [];
|
|
3938
|
+
if (!missingClosedSymbols.length) break;
|
|
3939
|
+
if (attempt < maxClosedBarAttempts) {
|
|
3940
|
+
await (0, import_async.delay)(closedBarRetryDelayMs);
|
|
3941
|
+
}
|
|
3942
|
+
}
|
|
3943
|
+
if (missingClosedSymbols.length) {
|
|
3944
|
+
throw new Error(
|
|
3945
|
+
`Coinalyze closed ${interval2} bar ${new Date(toMs).toISOString()} unavailable for ${missingClosedSymbols.join(",")}`
|
|
3946
|
+
);
|
|
3947
|
+
}
|
|
3837
3948
|
if (rows.length) {
|
|
3838
3949
|
await (0, import_timescale2.upsertDerivatives)(rows);
|
|
3839
3950
|
totalRows += rows.length;
|
|
3840
3951
|
}
|
|
3841
|
-
const
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
(rowsCountBySymbol.get(symbol) ?? 0) + 1
|
|
3847
|
-
);
|
|
3848
|
-
}
|
|
3849
|
-
const coverageRows = missingBatch.map((item) => {
|
|
3850
|
-
const normalizedSymbol = item.symbol.toUpperCase();
|
|
3851
|
-
const rowsCount = rowsCountBySymbol.get(normalizedSymbol) ?? 0;
|
|
3852
|
-
return {
|
|
3853
|
-
source: "coinalyze",
|
|
3854
|
-
symbol: item.symbol,
|
|
3855
|
-
interval: interval2,
|
|
3856
|
-
fromMs: cursor,
|
|
3857
|
-
toMs,
|
|
3858
|
-
rowsCount
|
|
3859
|
-
};
|
|
3952
|
+
const confirmedLiquidationWindow = (0, import_indicators.resolveCoinalyzeConfirmedIntradayCoverage)({
|
|
3953
|
+
interval: interval2,
|
|
3954
|
+
fromMs: group.fromMs,
|
|
3955
|
+
toMs,
|
|
3956
|
+
nowMs: coverageNowMs
|
|
3860
3957
|
});
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
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
|
+
}
|
|
3988
|
+
if (mode === "backtest") {
|
|
3989
|
+
const rowsCountBySymbol = /* @__PURE__ */ new Map();
|
|
3990
|
+
for (const row of rows) {
|
|
3991
|
+
const symbol = row.symbol.toUpperCase();
|
|
3992
|
+
rowsCountBySymbol.set(
|
|
3870
3993
|
symbol,
|
|
3994
|
+
(rowsCountBySymbol.get(symbol) ?? 0) + 1
|
|
3995
|
+
);
|
|
3996
|
+
}
|
|
3997
|
+
const coverageRows = missingBatch.map((item) => {
|
|
3998
|
+
const normalizedSymbol = item.symbol.toUpperCase();
|
|
3999
|
+
const rowsCount = rowsCountBySymbol.get(normalizedSymbol) ?? 0;
|
|
4000
|
+
return {
|
|
4001
|
+
source: "coinalyze",
|
|
4002
|
+
symbol: item.symbol,
|
|
3871
4003
|
interval: interval2,
|
|
3872
4004
|
fromMs: cursor,
|
|
3873
|
-
toMs
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
4005
|
+
toMs,
|
|
4006
|
+
rowsCount
|
|
4007
|
+
};
|
|
4008
|
+
});
|
|
4009
|
+
await (0, import_timescale2.upsertDerivativesBackfillCoverage)(coverageRows);
|
|
4010
|
+
for (const coverageRow of coverageRows) {
|
|
4011
|
+
const symbol = coverageRow.symbol.toUpperCase();
|
|
4012
|
+
edgesBySymbol.set(
|
|
4013
|
+
symbol,
|
|
4014
|
+
extendEdges(edgesBySymbol.get(symbol), cursor, toMs)
|
|
4015
|
+
);
|
|
4016
|
+
coverageKeys.add(
|
|
4017
|
+
coverageKey({
|
|
4018
|
+
symbol,
|
|
4019
|
+
interval: interval2,
|
|
4020
|
+
fromMs: cursor,
|
|
4021
|
+
toMs
|
|
4022
|
+
})
|
|
4023
|
+
);
|
|
4024
|
+
const coverageRanges = coverageRangesBySymbol.get(symbol) ?? [];
|
|
4025
|
+
coverageRanges.push({ fromMs: cursor, toMs });
|
|
4026
|
+
coverageRangesBySymbol.set(symbol, coverageRanges);
|
|
4027
|
+
}
|
|
3879
4028
|
}
|
|
3880
4029
|
}
|
|
3881
4030
|
}
|