@tradejs/cli 2.0.0 → 2.0.1
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 +143 -93
- package/dist/lib/aiTrainResearch.js +0 -1
- package/dist/lib/derivativesContextBackfill.js +127 -83
- package/dist/lib/marketContextPrepare.js +123 -83
- package/dist/scripts/aiTrain.js +0 -1
- package/dist/scripts/backtest.js +123 -83
- package/dist/scripts/derivativesIngest.js +11 -4
- package/dist/scripts/derivativesIngestCoinalyzeAll.js +8 -4
- package/dist/scripts/replay.js +123 -83
- package/dist/scripts/replayRunner.js +123 -83
- package/dist/scripts/runtimeParity.js +123 -83
- package/dist/scripts/signals.js +123 -83
- package/dist/scripts/signalsDaemon.js +123 -83
- package/package.json +9 -9
|
@@ -33,6 +33,7 @@ __export(derivativesContextBackfill_exports, {
|
|
|
33
33
|
backfillDerivativesContextForBacktest: () => backfillDerivativesContextForBacktest,
|
|
34
34
|
backfillDerivativesContextForSignals: () => backfillDerivativesContextForSignals,
|
|
35
35
|
formatCoinalyzeRequestError: () => formatCoinalyzeRequestError,
|
|
36
|
+
getMissingClosedDerivativesSymbols: () => getMissingClosedDerivativesSymbols,
|
|
36
37
|
groupDerivativesContextMissingFetchRanges: () => groupDerivativesContextMissingFetchRanges,
|
|
37
38
|
hasDerivativesContextCoverageRange: () => hasDerivativesContextCoverageRange,
|
|
38
39
|
isBacktestDerivativesContextEnabled: () => isBacktestDerivativesContextEnabled,
|
|
@@ -40,6 +41,7 @@ __export(derivativesContextBackfill_exports, {
|
|
|
40
41
|
isSignalsDerivativesContextEnabled: () => isSignalsDerivativesContextEnabled,
|
|
41
42
|
resolveDerivativesContextBackfillSymbols: () => resolveDerivativesContextBackfillSymbols,
|
|
42
43
|
resolveDerivativesContextBackfillWindow: () => resolveDerivativesContextBackfillWindow,
|
|
44
|
+
resolveDerivativesContextFetchFromMs: () => resolveDerivativesContextFetchFromMs,
|
|
43
45
|
resolveDerivativesContextIntervalBackfillWindow: () => resolveDerivativesContextIntervalBackfillWindow,
|
|
44
46
|
resolveDerivativesContextIntervals: () => resolveDerivativesContextIntervals,
|
|
45
47
|
resolveDerivativesContextLookbackMs: () => resolveDerivativesContextLookbackMs,
|
|
@@ -59,7 +61,7 @@ var import_userSettings = require("@tradejs/infra/userSettings");
|
|
|
59
61
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
60
62
|
var DAY_MS = 24 * HOUR_MS;
|
|
61
63
|
var DEFAULT_LOOKBACK_HOURS = 48;
|
|
62
|
-
var
|
|
64
|
+
var SOURCE_INTERVALS = ["15m"];
|
|
63
65
|
var coinalyzeIntervalMap = {
|
|
64
66
|
"15m": "15min",
|
|
65
67
|
"1h": "1hour"
|
|
@@ -120,10 +122,7 @@ var isDerivativesContextBackfillEnabled = (env) => {
|
|
|
120
122
|
var shouldBackfillDerivativesContextForBacktest = (params) => !params.cacheOnly && (params.aiEnabled || params.mlEnabled) && isBacktestDerivativesContextEnabled();
|
|
121
123
|
var shouldBackfillDerivativesContextForSignals = (params) => !params.cacheOnly && isSignalsDerivativesContextEnabled();
|
|
122
124
|
var resolveDerivativesContextIntervals = () => {
|
|
123
|
-
|
|
124
|
-
process.env.DERIVATIVES_CONTEXT_INTERVALS
|
|
125
|
-
);
|
|
126
|
-
return intervals.length ? intervals : DEFAULT_INTERVALS;
|
|
125
|
+
return [...SOURCE_INTERVALS];
|
|
127
126
|
};
|
|
128
127
|
var resolveDerivativesContextLookbackMs = () => {
|
|
129
128
|
const hours = Number(process.env.DERIVATIVES_CONTEXT_LOOKBACK_HOURS);
|
|
@@ -158,9 +157,10 @@ var resolveDerivativesContextBackfillWindow = (params) => {
|
|
|
158
157
|
};
|
|
159
158
|
var resolveDerivativesContextIntervalBackfillWindow = (params) => {
|
|
160
159
|
const intervalMs = derivativesIntervalMs(params.interval);
|
|
160
|
+
const alignedToMs = params.closedOnly ? (0, import_indicators.getLastClosedDerivativesBarStartMs)(params.toMs, params.interval) : Math.floor(params.toMs / intervalMs) * intervalMs;
|
|
161
161
|
return {
|
|
162
162
|
fromMs: Math.floor(params.fromMs / intervalMs) * intervalMs,
|
|
163
|
-
toMs:
|
|
163
|
+
toMs: alignedToMs,
|
|
164
164
|
intervalMs
|
|
165
165
|
};
|
|
166
166
|
};
|
|
@@ -178,6 +178,7 @@ var resolveDerivativesContextMissingFetchFromMs = (params) => {
|
|
|
178
178
|
}
|
|
179
179
|
return null;
|
|
180
180
|
};
|
|
181
|
+
var resolveDerivativesContextFetchFromMs = (params) => resolveDerivativesContextMissingFetchFromMs(params) ?? (params.refreshClosedTail ? params.toMs : null);
|
|
181
182
|
var countBackfillWindows = (params) => {
|
|
182
183
|
let count = 0;
|
|
183
184
|
let cursor = params.fromMs;
|
|
@@ -244,6 +245,14 @@ var groupDerivativesContextMissingFetchRanges = (ranges) => {
|
|
|
244
245
|
}
|
|
245
246
|
return [...groups.entries()].sort(([a], [b]) => a - b).map(([fromMs, items]) => ({ fromMs, items }));
|
|
246
247
|
};
|
|
248
|
+
var getMissingClosedDerivativesSymbols = (params) => {
|
|
249
|
+
const availableSymbols = new Set(
|
|
250
|
+
params.rows.filter((row) => row.ts.getTime() === params.expectedTimestamp).map((row) => row.symbol.trim().toUpperCase())
|
|
251
|
+
);
|
|
252
|
+
return params.symbols.filter(
|
|
253
|
+
(symbol) => !availableSymbols.has(symbol.trim().toUpperCase())
|
|
254
|
+
);
|
|
255
|
+
};
|
|
247
256
|
var coverageKey = (params) => [
|
|
248
257
|
params.symbol.trim().toUpperCase(),
|
|
249
258
|
params.interval,
|
|
@@ -523,7 +532,8 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
523
532
|
...resolveDerivativesContextIntervalBackfillWindow({
|
|
524
533
|
fromMs,
|
|
525
534
|
toMs: safeEndMs,
|
|
526
|
-
interval
|
|
535
|
+
interval,
|
|
536
|
+
closedOnly: mode === "signals"
|
|
527
537
|
})
|
|
528
538
|
})).filter((item) => item.toMs > item.fromMs);
|
|
529
539
|
if (!intervalWindows.length) {
|
|
@@ -582,7 +592,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
582
592
|
}),
|
|
583
593
|
0
|
|
584
594
|
);
|
|
585
|
-
const allBackfillWindowsCached = intervalWindows.every((window) => {
|
|
595
|
+
const allBackfillWindowsCached = mode !== "signals" && intervalWindows.every((window) => {
|
|
586
596
|
const edgesBySymbol = edgesByInterval.get(window.interval);
|
|
587
597
|
const coverageKeys = coverageKeysByInterval.get(window.interval);
|
|
588
598
|
const backfillWindows = buildBackfillWindows({
|
|
@@ -712,7 +722,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
712
722
|
return null;
|
|
713
723
|
}
|
|
714
724
|
const normalizedSymbol = item.symbol.toUpperCase();
|
|
715
|
-
const coverageFromMs = resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
725
|
+
const coverageFromMs = mode === "signals" ? cursor : resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
716
726
|
ranges: coverageRangesBySymbol.get(normalizedSymbol),
|
|
717
727
|
fromMs: cursor,
|
|
718
728
|
toMs,
|
|
@@ -722,16 +732,20 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
722
732
|
return null;
|
|
723
733
|
}
|
|
724
734
|
const edges = edgesBySymbol.get(normalizedSymbol);
|
|
725
|
-
const edgesFromMs =
|
|
735
|
+
const edgesFromMs = resolveDerivativesContextFetchFromMs({
|
|
726
736
|
edges,
|
|
727
737
|
fromMs: cursor,
|
|
728
738
|
toMs,
|
|
729
|
-
intervalMs
|
|
739
|
+
intervalMs,
|
|
740
|
+
refreshClosedTail: mode === "signals"
|
|
730
741
|
});
|
|
731
742
|
if (edgesFromMs == null) {
|
|
732
743
|
return null;
|
|
733
744
|
}
|
|
734
|
-
return {
|
|
745
|
+
return {
|
|
746
|
+
item,
|
|
747
|
+
fromMs: Math.max(coverageFromMs, edgesFromMs)
|
|
748
|
+
};
|
|
735
749
|
}).filter(
|
|
736
750
|
(item) => item != null
|
|
737
751
|
);
|
|
@@ -745,85 +759,113 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
745
759
|
const marketSymbols = missingBatch.map(
|
|
746
760
|
(item) => item.marketSymbol
|
|
747
761
|
);
|
|
748
|
-
const
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
const
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
762
|
+
const maxClosedBarAttempts = mode === "signals" ? asInt(
|
|
763
|
+
process.env.DERIVATIVES_CONTEXT_CLOSED_BAR_MAX_ATTEMPTS,
|
|
764
|
+
3
|
|
765
|
+
) : 1;
|
|
766
|
+
const closedBarRetryDelayMs = asInt(
|
|
767
|
+
process.env.DERIVATIVES_CONTEXT_CLOSED_BAR_RETRY_DELAY_MS,
|
|
768
|
+
2e3
|
|
769
|
+
);
|
|
770
|
+
let rows = [];
|
|
771
|
+
let missingClosedSymbols = [];
|
|
772
|
+
for (let attempt = 1; attempt <= maxClosedBarAttempts; attempt += 1) {
|
|
773
|
+
const oiMap = await fetchMetricBatch({
|
|
774
|
+
endpoint: oiPath,
|
|
775
|
+
metric: "oi",
|
|
776
|
+
marketSymbols,
|
|
777
|
+
apiKey,
|
|
778
|
+
interval,
|
|
779
|
+
fromMs: group.fromMs,
|
|
780
|
+
toMs
|
|
781
|
+
});
|
|
782
|
+
const fundingMap = await fetchMetricBatch({
|
|
783
|
+
endpoint: fundingPath,
|
|
784
|
+
metric: "funding",
|
|
785
|
+
marketSymbols,
|
|
786
|
+
apiKey,
|
|
787
|
+
interval,
|
|
788
|
+
fromMs: group.fromMs,
|
|
789
|
+
toMs
|
|
790
|
+
});
|
|
791
|
+
const liqMap = await fetchMetricBatch({
|
|
792
|
+
endpoint: liqPath,
|
|
793
|
+
metric: "liq",
|
|
794
|
+
marketSymbols,
|
|
795
|
+
apiKey,
|
|
796
|
+
interval,
|
|
797
|
+
fromMs: group.fromMs,
|
|
798
|
+
toMs
|
|
782
799
|
});
|
|
783
|
-
|
|
784
|
-
|
|
800
|
+
rows = missingBatch.flatMap((item) => {
|
|
801
|
+
const marketSymbol = item.marketSymbol.toUpperCase();
|
|
802
|
+
const points = (0, import_indicators.mergeCoinalyzeMetrics)({
|
|
803
|
+
symbol: item.symbol,
|
|
804
|
+
oiRaw: oiMap.get(marketSymbol) ?? [],
|
|
805
|
+
fundingRaw: fundingMap.get(marketSymbol) ?? [],
|
|
806
|
+
liqRaw: liqMap.get(marketSymbol) ?? []
|
|
807
|
+
});
|
|
808
|
+
return (0, import_indicators.coinalyzePointsToRows)(points, interval, "coinalyze");
|
|
809
|
+
});
|
|
810
|
+
missingClosedSymbols = mode === "signals" ? getMissingClosedDerivativesSymbols({
|
|
811
|
+
symbols: missingBatch.map((item) => item.symbol),
|
|
812
|
+
rows,
|
|
813
|
+
expectedTimestamp: toMs
|
|
814
|
+
}) : [];
|
|
815
|
+
if (!missingClosedSymbols.length) break;
|
|
816
|
+
if (attempt < maxClosedBarAttempts) {
|
|
817
|
+
await (0, import_async.delay)(closedBarRetryDelayMs);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
if (missingClosedSymbols.length) {
|
|
821
|
+
throw new Error(
|
|
822
|
+
`Coinalyze closed ${interval} bar ${new Date(toMs).toISOString()} unavailable for ${missingClosedSymbols.join(",")}`
|
|
823
|
+
);
|
|
824
|
+
}
|
|
785
825
|
if (rows.length) {
|
|
786
826
|
await (0, import_timescale.upsertDerivatives)(rows);
|
|
787
827
|
totalRows += rows.length;
|
|
788
828
|
}
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
const
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
(rowsCountBySymbol.get(symbol) ?? 0) + 1
|
|
795
|
-
);
|
|
796
|
-
}
|
|
797
|
-
const coverageRows = missingBatch.map((item) => {
|
|
798
|
-
const normalizedSymbol = item.symbol.toUpperCase();
|
|
799
|
-
const rowsCount = rowsCountBySymbol.get(normalizedSymbol) ?? 0;
|
|
800
|
-
return {
|
|
801
|
-
source: "coinalyze",
|
|
802
|
-
symbol: item.symbol,
|
|
803
|
-
interval,
|
|
804
|
-
fromMs: cursor,
|
|
805
|
-
toMs,
|
|
806
|
-
rowsCount
|
|
807
|
-
};
|
|
808
|
-
});
|
|
809
|
-
await (0, import_timescale.upsertDerivativesBackfillCoverage)(coverageRows);
|
|
810
|
-
for (const coverageRow of coverageRows) {
|
|
811
|
-
const symbol = coverageRow.symbol.toUpperCase();
|
|
812
|
-
edgesBySymbol.set(
|
|
813
|
-
symbol,
|
|
814
|
-
extendEdges(edgesBySymbol.get(symbol), cursor, toMs)
|
|
815
|
-
);
|
|
816
|
-
coverageKeys.add(
|
|
817
|
-
coverageKey({
|
|
829
|
+
if (mode === "backtest") {
|
|
830
|
+
const rowsCountBySymbol = /* @__PURE__ */ new Map();
|
|
831
|
+
for (const row of rows) {
|
|
832
|
+
const symbol = row.symbol.toUpperCase();
|
|
833
|
+
rowsCountBySymbol.set(
|
|
818
834
|
symbol,
|
|
835
|
+
(rowsCountBySymbol.get(symbol) ?? 0) + 1
|
|
836
|
+
);
|
|
837
|
+
}
|
|
838
|
+
const coverageRows = missingBatch.map((item) => {
|
|
839
|
+
const normalizedSymbol = item.symbol.toUpperCase();
|
|
840
|
+
const rowsCount = rowsCountBySymbol.get(normalizedSymbol) ?? 0;
|
|
841
|
+
return {
|
|
842
|
+
source: "coinalyze",
|
|
843
|
+
symbol: item.symbol,
|
|
819
844
|
interval,
|
|
820
845
|
fromMs: cursor,
|
|
821
|
-
toMs
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
846
|
+
toMs,
|
|
847
|
+
rowsCount
|
|
848
|
+
};
|
|
849
|
+
});
|
|
850
|
+
await (0, import_timescale.upsertDerivativesBackfillCoverage)(coverageRows);
|
|
851
|
+
for (const coverageRow of coverageRows) {
|
|
852
|
+
const symbol = coverageRow.symbol.toUpperCase();
|
|
853
|
+
edgesBySymbol.set(
|
|
854
|
+
symbol,
|
|
855
|
+
extendEdges(edgesBySymbol.get(symbol), cursor, toMs)
|
|
856
|
+
);
|
|
857
|
+
coverageKeys.add(
|
|
858
|
+
coverageKey({
|
|
859
|
+
symbol,
|
|
860
|
+
interval,
|
|
861
|
+
fromMs: cursor,
|
|
862
|
+
toMs
|
|
863
|
+
})
|
|
864
|
+
);
|
|
865
|
+
const coverageRanges = coverageRangesBySymbol.get(symbol) ?? [];
|
|
866
|
+
coverageRanges.push({ fromMs: cursor, toMs });
|
|
867
|
+
coverageRangesBySymbol.set(symbol, coverageRanges);
|
|
868
|
+
}
|
|
827
869
|
}
|
|
828
870
|
}
|
|
829
871
|
}
|
|
@@ -883,6 +925,7 @@ var backfillDerivativesContextForSignals = async (params) => backfillDerivatives
|
|
|
883
925
|
backfillDerivativesContextForBacktest,
|
|
884
926
|
backfillDerivativesContextForSignals,
|
|
885
927
|
formatCoinalyzeRequestError,
|
|
928
|
+
getMissingClosedDerivativesSymbols,
|
|
886
929
|
groupDerivativesContextMissingFetchRanges,
|
|
887
930
|
hasDerivativesContextCoverageRange,
|
|
888
931
|
isBacktestDerivativesContextEnabled,
|
|
@@ -890,6 +933,7 @@ var backfillDerivativesContextForSignals = async (params) => backfillDerivatives
|
|
|
890
933
|
isSignalsDerivativesContextEnabled,
|
|
891
934
|
resolveDerivativesContextBackfillSymbols,
|
|
892
935
|
resolveDerivativesContextBackfillWindow,
|
|
936
|
+
resolveDerivativesContextFetchFromMs,
|
|
893
937
|
resolveDerivativesContextIntervalBackfillWindow,
|
|
894
938
|
resolveDerivativesContextIntervals,
|
|
895
939
|
resolveDerivativesContextLookbackMs,
|
|
@@ -2434,7 +2434,7 @@ var import_userSettings = require("@tradejs/infra/userSettings");
|
|
|
2434
2434
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
2435
2435
|
var DAY_MS2 = 24 * HOUR_MS;
|
|
2436
2436
|
var DEFAULT_LOOKBACK_HOURS = 48;
|
|
2437
|
-
var
|
|
2437
|
+
var SOURCE_INTERVALS = ["15m"];
|
|
2438
2438
|
var coinalyzeIntervalMap = {
|
|
2439
2439
|
"15m": "15min",
|
|
2440
2440
|
"1h": "1hour"
|
|
@@ -2495,10 +2495,7 @@ var isDerivativesContextBackfillEnabled = (env) => {
|
|
|
2495
2495
|
var shouldBackfillDerivativesContextForBacktest = (params) => !params.cacheOnly && (params.aiEnabled || params.mlEnabled) && isBacktestDerivativesContextEnabled();
|
|
2496
2496
|
var shouldBackfillDerivativesContextForSignals = (params) => !params.cacheOnly && isSignalsDerivativesContextEnabled();
|
|
2497
2497
|
var resolveDerivativesContextIntervals = () => {
|
|
2498
|
-
|
|
2499
|
-
process.env.DERIVATIVES_CONTEXT_INTERVALS
|
|
2500
|
-
);
|
|
2501
|
-
return intervals.length ? intervals : DEFAULT_INTERVALS;
|
|
2498
|
+
return [...SOURCE_INTERVALS];
|
|
2502
2499
|
};
|
|
2503
2500
|
var resolveDerivativesContextLookbackMs = () => {
|
|
2504
2501
|
const hours = Number(process.env.DERIVATIVES_CONTEXT_LOOKBACK_HOURS);
|
|
@@ -2533,9 +2530,10 @@ var resolveDerivativesContextBackfillWindow = (params) => {
|
|
|
2533
2530
|
};
|
|
2534
2531
|
var resolveDerivativesContextIntervalBackfillWindow = (params) => {
|
|
2535
2532
|
const intervalMs = derivativesIntervalMs(params.interval);
|
|
2533
|
+
const alignedToMs = params.closedOnly ? (0, import_indicators.getLastClosedDerivativesBarStartMs)(params.toMs, params.interval) : Math.floor(params.toMs / intervalMs) * intervalMs;
|
|
2536
2534
|
return {
|
|
2537
2535
|
fromMs: Math.floor(params.fromMs / intervalMs) * intervalMs,
|
|
2538
|
-
toMs:
|
|
2536
|
+
toMs: alignedToMs,
|
|
2539
2537
|
intervalMs
|
|
2540
2538
|
};
|
|
2541
2539
|
};
|
|
@@ -2553,6 +2551,7 @@ var resolveDerivativesContextMissingFetchFromMs = (params) => {
|
|
|
2553
2551
|
}
|
|
2554
2552
|
return null;
|
|
2555
2553
|
};
|
|
2554
|
+
var resolveDerivativesContextFetchFromMs = (params) => resolveDerivativesContextMissingFetchFromMs(params) ?? (params.refreshClosedTail ? params.toMs : null);
|
|
2556
2555
|
var countBackfillWindows = (params) => {
|
|
2557
2556
|
let count = 0;
|
|
2558
2557
|
let cursor = params.fromMs;
|
|
@@ -2616,6 +2615,14 @@ var groupDerivativesContextMissingFetchRanges = (ranges) => {
|
|
|
2616
2615
|
}
|
|
2617
2616
|
return [...groups.entries()].sort(([a], [b]) => a - b).map(([fromMs, items]) => ({ fromMs, items }));
|
|
2618
2617
|
};
|
|
2618
|
+
var getMissingClosedDerivativesSymbols = (params) => {
|
|
2619
|
+
const availableSymbols = new Set(
|
|
2620
|
+
params.rows.filter((row) => row.ts.getTime() === params.expectedTimestamp).map((row) => row.symbol.trim().toUpperCase())
|
|
2621
|
+
);
|
|
2622
|
+
return params.symbols.filter(
|
|
2623
|
+
(symbol) => !availableSymbols.has(symbol.trim().toUpperCase())
|
|
2624
|
+
);
|
|
2625
|
+
};
|
|
2619
2626
|
var coverageKey = (params) => [
|
|
2620
2627
|
params.symbol.trim().toUpperCase(),
|
|
2621
2628
|
params.interval,
|
|
@@ -2895,7 +2902,8 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
2895
2902
|
...resolveDerivativesContextIntervalBackfillWindow({
|
|
2896
2903
|
fromMs,
|
|
2897
2904
|
toMs: safeEndMs,
|
|
2898
|
-
interval
|
|
2905
|
+
interval,
|
|
2906
|
+
closedOnly: mode === "signals"
|
|
2899
2907
|
})
|
|
2900
2908
|
})).filter((item) => item.toMs > item.fromMs);
|
|
2901
2909
|
if (!intervalWindows.length) {
|
|
@@ -2954,7 +2962,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
2954
2962
|
}),
|
|
2955
2963
|
0
|
|
2956
2964
|
);
|
|
2957
|
-
const allBackfillWindowsCached = intervalWindows.every((window2) => {
|
|
2965
|
+
const allBackfillWindowsCached = mode !== "signals" && intervalWindows.every((window2) => {
|
|
2958
2966
|
const edgesBySymbol = edgesByInterval.get(window2.interval);
|
|
2959
2967
|
const coverageKeys = coverageKeysByInterval.get(window2.interval);
|
|
2960
2968
|
const backfillWindows = buildBackfillWindows({
|
|
@@ -3084,7 +3092,7 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3084
3092
|
return null;
|
|
3085
3093
|
}
|
|
3086
3094
|
const normalizedSymbol = item.symbol.toUpperCase();
|
|
3087
|
-
const coverageFromMs = resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
3095
|
+
const coverageFromMs = mode === "signals" ? cursor : resolveDerivativesContextMissingCoverageFetchFromMs({
|
|
3088
3096
|
ranges: coverageRangesBySymbol.get(normalizedSymbol),
|
|
3089
3097
|
fromMs: cursor,
|
|
3090
3098
|
toMs,
|
|
@@ -3094,16 +3102,20 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3094
3102
|
return null;
|
|
3095
3103
|
}
|
|
3096
3104
|
const edges = edgesBySymbol.get(normalizedSymbol);
|
|
3097
|
-
const edgesFromMs =
|
|
3105
|
+
const edgesFromMs = resolveDerivativesContextFetchFromMs({
|
|
3098
3106
|
edges,
|
|
3099
3107
|
fromMs: cursor,
|
|
3100
3108
|
toMs,
|
|
3101
|
-
intervalMs
|
|
3109
|
+
intervalMs,
|
|
3110
|
+
refreshClosedTail: mode === "signals"
|
|
3102
3111
|
});
|
|
3103
3112
|
if (edgesFromMs == null) {
|
|
3104
3113
|
return null;
|
|
3105
3114
|
}
|
|
3106
|
-
return {
|
|
3115
|
+
return {
|
|
3116
|
+
item,
|
|
3117
|
+
fromMs: Math.max(coverageFromMs, edgesFromMs)
|
|
3118
|
+
};
|
|
3107
3119
|
}).filter(
|
|
3108
3120
|
(item) => item != null
|
|
3109
3121
|
);
|
|
@@ -3117,85 +3129,113 @@ var backfillDerivativesContext = async (params, enabled, mode) => {
|
|
|
3117
3129
|
const marketSymbols = missingBatch.map(
|
|
3118
3130
|
(item) => item.marketSymbol
|
|
3119
3131
|
);
|
|
3120
|
-
const
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
const marketSymbol = item.marketSymbol.toUpperCase();
|
|
3149
|
-
const points = (0, import_indicators.mergeCoinalyzeMetrics)({
|
|
3150
|
-
symbol: item.symbol,
|
|
3151
|
-
oiRaw: oiMap.get(marketSymbol) ?? [],
|
|
3152
|
-
fundingRaw: fundingMap.get(marketSymbol) ?? [],
|
|
3153
|
-
liqRaw: liqMap.get(marketSymbol) ?? []
|
|
3132
|
+
const maxClosedBarAttempts = mode === "signals" ? asInt2(
|
|
3133
|
+
process.env.DERIVATIVES_CONTEXT_CLOSED_BAR_MAX_ATTEMPTS,
|
|
3134
|
+
3
|
|
3135
|
+
) : 1;
|
|
3136
|
+
const closedBarRetryDelayMs = asInt2(
|
|
3137
|
+
process.env.DERIVATIVES_CONTEXT_CLOSED_BAR_RETRY_DELAY_MS,
|
|
3138
|
+
2e3
|
|
3139
|
+
);
|
|
3140
|
+
let rows = [];
|
|
3141
|
+
let missingClosedSymbols = [];
|
|
3142
|
+
for (let attempt = 1; attempt <= maxClosedBarAttempts; attempt += 1) {
|
|
3143
|
+
const oiMap = await fetchMetricBatch({
|
|
3144
|
+
endpoint: oiPath,
|
|
3145
|
+
metric: "oi",
|
|
3146
|
+
marketSymbols,
|
|
3147
|
+
apiKey,
|
|
3148
|
+
interval,
|
|
3149
|
+
fromMs: group.fromMs,
|
|
3150
|
+
toMs
|
|
3151
|
+
});
|
|
3152
|
+
const fundingMap = await fetchMetricBatch({
|
|
3153
|
+
endpoint: fundingPath,
|
|
3154
|
+
metric: "funding",
|
|
3155
|
+
marketSymbols,
|
|
3156
|
+
apiKey,
|
|
3157
|
+
interval,
|
|
3158
|
+
fromMs: group.fromMs,
|
|
3159
|
+
toMs
|
|
3154
3160
|
});
|
|
3155
|
-
|
|
3156
|
-
|
|
3161
|
+
const liqMap = await fetchMetricBatch({
|
|
3162
|
+
endpoint: liqPath,
|
|
3163
|
+
metric: "liq",
|
|
3164
|
+
marketSymbols,
|
|
3165
|
+
apiKey,
|
|
3166
|
+
interval,
|
|
3167
|
+
fromMs: group.fromMs,
|
|
3168
|
+
toMs
|
|
3169
|
+
});
|
|
3170
|
+
rows = missingBatch.flatMap((item) => {
|
|
3171
|
+
const marketSymbol = item.marketSymbol.toUpperCase();
|
|
3172
|
+
const points = (0, import_indicators.mergeCoinalyzeMetrics)({
|
|
3173
|
+
symbol: item.symbol,
|
|
3174
|
+
oiRaw: oiMap.get(marketSymbol) ?? [],
|
|
3175
|
+
fundingRaw: fundingMap.get(marketSymbol) ?? [],
|
|
3176
|
+
liqRaw: liqMap.get(marketSymbol) ?? []
|
|
3177
|
+
});
|
|
3178
|
+
return (0, import_indicators.coinalyzePointsToRows)(points, interval, "coinalyze");
|
|
3179
|
+
});
|
|
3180
|
+
missingClosedSymbols = mode === "signals" ? getMissingClosedDerivativesSymbols({
|
|
3181
|
+
symbols: missingBatch.map((item) => item.symbol),
|
|
3182
|
+
rows,
|
|
3183
|
+
expectedTimestamp: toMs
|
|
3184
|
+
}) : [];
|
|
3185
|
+
if (!missingClosedSymbols.length) break;
|
|
3186
|
+
if (attempt < maxClosedBarAttempts) {
|
|
3187
|
+
await (0, import_async.delay)(closedBarRetryDelayMs);
|
|
3188
|
+
}
|
|
3189
|
+
}
|
|
3190
|
+
if (missingClosedSymbols.length) {
|
|
3191
|
+
throw new Error(
|
|
3192
|
+
`Coinalyze closed ${interval} bar ${new Date(toMs).toISOString()} unavailable for ${missingClosedSymbols.join(",")}`
|
|
3193
|
+
);
|
|
3194
|
+
}
|
|
3157
3195
|
if (rows.length) {
|
|
3158
3196
|
await (0, import_timescale2.upsertDerivatives)(rows);
|
|
3159
3197
|
totalRows += rows.length;
|
|
3160
3198
|
}
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
const
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
(rowsCountBySymbol.get(symbol) ?? 0) + 1
|
|
3167
|
-
);
|
|
3168
|
-
}
|
|
3169
|
-
const coverageRows = missingBatch.map((item) => {
|
|
3170
|
-
const normalizedSymbol = item.symbol.toUpperCase();
|
|
3171
|
-
const rowsCount = rowsCountBySymbol.get(normalizedSymbol) ?? 0;
|
|
3172
|
-
return {
|
|
3173
|
-
source: "coinalyze",
|
|
3174
|
-
symbol: item.symbol,
|
|
3175
|
-
interval,
|
|
3176
|
-
fromMs: cursor,
|
|
3177
|
-
toMs,
|
|
3178
|
-
rowsCount
|
|
3179
|
-
};
|
|
3180
|
-
});
|
|
3181
|
-
await (0, import_timescale2.upsertDerivativesBackfillCoverage)(coverageRows);
|
|
3182
|
-
for (const coverageRow of coverageRows) {
|
|
3183
|
-
const symbol = coverageRow.symbol.toUpperCase();
|
|
3184
|
-
edgesBySymbol.set(
|
|
3185
|
-
symbol,
|
|
3186
|
-
extendEdges(edgesBySymbol.get(symbol), cursor, toMs)
|
|
3187
|
-
);
|
|
3188
|
-
coverageKeys.add(
|
|
3189
|
-
coverageKey({
|
|
3199
|
+
if (mode === "backtest") {
|
|
3200
|
+
const rowsCountBySymbol = /* @__PURE__ */ new Map();
|
|
3201
|
+
for (const row of rows) {
|
|
3202
|
+
const symbol = row.symbol.toUpperCase();
|
|
3203
|
+
rowsCountBySymbol.set(
|
|
3190
3204
|
symbol,
|
|
3205
|
+
(rowsCountBySymbol.get(symbol) ?? 0) + 1
|
|
3206
|
+
);
|
|
3207
|
+
}
|
|
3208
|
+
const coverageRows = missingBatch.map((item) => {
|
|
3209
|
+
const normalizedSymbol = item.symbol.toUpperCase();
|
|
3210
|
+
const rowsCount = rowsCountBySymbol.get(normalizedSymbol) ?? 0;
|
|
3211
|
+
return {
|
|
3212
|
+
source: "coinalyze",
|
|
3213
|
+
symbol: item.symbol,
|
|
3191
3214
|
interval,
|
|
3192
3215
|
fromMs: cursor,
|
|
3193
|
-
toMs
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3216
|
+
toMs,
|
|
3217
|
+
rowsCount
|
|
3218
|
+
};
|
|
3219
|
+
});
|
|
3220
|
+
await (0, import_timescale2.upsertDerivativesBackfillCoverage)(coverageRows);
|
|
3221
|
+
for (const coverageRow of coverageRows) {
|
|
3222
|
+
const symbol = coverageRow.symbol.toUpperCase();
|
|
3223
|
+
edgesBySymbol.set(
|
|
3224
|
+
symbol,
|
|
3225
|
+
extendEdges(edgesBySymbol.get(symbol), cursor, toMs)
|
|
3226
|
+
);
|
|
3227
|
+
coverageKeys.add(
|
|
3228
|
+
coverageKey({
|
|
3229
|
+
symbol,
|
|
3230
|
+
interval,
|
|
3231
|
+
fromMs: cursor,
|
|
3232
|
+
toMs
|
|
3233
|
+
})
|
|
3234
|
+
);
|
|
3235
|
+
const coverageRanges = coverageRangesBySymbol.get(symbol) ?? [];
|
|
3236
|
+
coverageRanges.push({ fromMs: cursor, toMs });
|
|
3237
|
+
coverageRangesBySymbol.set(symbol, coverageRanges);
|
|
3238
|
+
}
|
|
3199
3239
|
}
|
|
3200
3240
|
}
|
|
3201
3241
|
}
|
package/dist/scripts/aiTrain.js
CHANGED
|
@@ -2510,7 +2510,6 @@ var RESEARCH_CONTEXT_ENV_KEYS = [
|
|
|
2510
2510
|
"INTERVAL",
|
|
2511
2511
|
"DERIVATIVES_CONTEXT_ENABLED",
|
|
2512
2512
|
"DERIVATIVES_CONTEXT_TARGET_ENABLED",
|
|
2513
|
-
"DERIVATIVES_CONTEXT_INTERVALS",
|
|
2514
2513
|
"DERIVATIVES_CONTEXT_LOOKBACK_HOURS",
|
|
2515
2514
|
"DERIVATIVES_CONTEXT_EXTRA_REFERENCE_SYMBOLS",
|
|
2516
2515
|
"DERIVATIVES_CONTEXT_EXCHANGE_PRIORITY",
|