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