@tradejs/infra 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/timescale.d.mts +29 -1
- package/dist/timescale.d.ts +29 -1
- package/dist/timescale.js +170 -0
- package/dist/timescale.mjs +168 -0
- package/package.json +2 -2
package/dist/timescale.d.mts
CHANGED
|
@@ -50,6 +50,34 @@ declare function upsertDerivativesBackfillCoverage(rows: Array<{
|
|
|
50
50
|
toMs: number;
|
|
51
51
|
rowsCount: number;
|
|
52
52
|
}>): Promise<void>;
|
|
53
|
+
type DerivativesMetricCoverageMetric = 'liquidation';
|
|
54
|
+
declare function getDerivativesMetricCoverage(params: {
|
|
55
|
+
source: string;
|
|
56
|
+
metric: DerivativesMetricCoverageMetric;
|
|
57
|
+
symbols: string[];
|
|
58
|
+
interval: DerivativesInterval;
|
|
59
|
+
fromMs: number;
|
|
60
|
+
toMs: number;
|
|
61
|
+
}): Promise<{
|
|
62
|
+
symbol: string;
|
|
63
|
+
interval: DerivativesInterval;
|
|
64
|
+
fromMs: number;
|
|
65
|
+
toMs: number;
|
|
66
|
+
eventRowsCount: number;
|
|
67
|
+
zeroRowsCount: number;
|
|
68
|
+
}[]>;
|
|
69
|
+
declare function applyDerivativesMetricCoverage(rows: Array<{
|
|
70
|
+
source: string;
|
|
71
|
+
metric: DerivativesMetricCoverageMetric;
|
|
72
|
+
symbol: string;
|
|
73
|
+
interval: DerivativesInterval;
|
|
74
|
+
fromMs: number;
|
|
75
|
+
toMs: number;
|
|
76
|
+
eventRowsCount: number;
|
|
77
|
+
}>): Promise<{
|
|
78
|
+
symbol: string;
|
|
79
|
+
zeroRowsCount: number;
|
|
80
|
+
}[]>;
|
|
53
81
|
declare function getDerivativesWindow(params: {
|
|
54
82
|
symbol: string;
|
|
55
83
|
intervals: DerivativesInterval[];
|
|
@@ -271,4 +299,4 @@ declare function findContinuityGap(provider: string, symbol: string, interval: n
|
|
|
271
299
|
diffSeconds: number;
|
|
272
300
|
} | null>;
|
|
273
301
|
|
|
274
|
-
export { type CandleRow, type DeprecatedMarketContextCleanupItem, type MarketFeatureAsOf, cleanupDeprecatedMarketContext, closeTimescalePool, deleteCandles, findContinuityGap, getCandlesRange, getDataEdges, getDataEdgesForSymbols, getDerivativesBackfillCoverage, getDerivativesDataEdgesForSymbols, getDerivativesRangeForSymbols, getDerivativesSummary, getDerivativesWindow, getLatestMarketBreadth, getLatestMarketCmcExchangeLiquidityContext, getLatestMarketCmcFearGreedContext, getLatestMarketCmcIndexContexts, getLatestMarketGlobalContext, getLatestMarketReferenceAssetContexts, getLatestMarketTradeFlow, getMarketBreadthCoverage, getMarketCmcExchangeLiquidityContextCoverage, getMarketCmcFearGreedContextCoverage, getMarketCmcIndexContextCoverage, getMarketContextBackfillCoverage, getMarketGlobalContextCoverage, getMarketReferenceAssetContextCoverage, getMarketTradeFlowCoverage, getSpreadRangeForSymbols, getSpreadSummary, toRows, upsertCandles, upsertDerivatives, upsertDerivativesBackfillCoverage, upsertMarketBreadthRows, upsertMarketCmcExchangeLiquidityContextRows, upsertMarketCmcFearGreedContextRows, upsertMarketCmcIndexContextRows, upsertMarketContextBackfillCoverage, upsertMarketGlobalContextRows, upsertMarketReferenceAssetContextRows, upsertMarketTradeFlowRows, upsertSpreadRows, waitForDbReady };
|
|
302
|
+
export { type CandleRow, type DeprecatedMarketContextCleanupItem, type DerivativesMetricCoverageMetric, type MarketFeatureAsOf, applyDerivativesMetricCoverage, cleanupDeprecatedMarketContext, closeTimescalePool, deleteCandles, findContinuityGap, getCandlesRange, getDataEdges, getDataEdgesForSymbols, getDerivativesBackfillCoverage, getDerivativesDataEdgesForSymbols, getDerivativesMetricCoverage, getDerivativesRangeForSymbols, getDerivativesSummary, getDerivativesWindow, getLatestMarketBreadth, getLatestMarketCmcExchangeLiquidityContext, getLatestMarketCmcFearGreedContext, getLatestMarketCmcIndexContexts, getLatestMarketGlobalContext, getLatestMarketReferenceAssetContexts, getLatestMarketTradeFlow, getMarketBreadthCoverage, getMarketCmcExchangeLiquidityContextCoverage, getMarketCmcFearGreedContextCoverage, getMarketCmcIndexContextCoverage, getMarketContextBackfillCoverage, getMarketGlobalContextCoverage, getMarketReferenceAssetContextCoverage, getMarketTradeFlowCoverage, getSpreadRangeForSymbols, getSpreadSummary, toRows, upsertCandles, upsertDerivatives, upsertDerivativesBackfillCoverage, upsertMarketBreadthRows, upsertMarketCmcExchangeLiquidityContextRows, upsertMarketCmcFearGreedContextRows, upsertMarketCmcIndexContextRows, upsertMarketContextBackfillCoverage, upsertMarketGlobalContextRows, upsertMarketReferenceAssetContextRows, upsertMarketTradeFlowRows, upsertSpreadRows, waitForDbReady };
|
package/dist/timescale.d.ts
CHANGED
|
@@ -50,6 +50,34 @@ declare function upsertDerivativesBackfillCoverage(rows: Array<{
|
|
|
50
50
|
toMs: number;
|
|
51
51
|
rowsCount: number;
|
|
52
52
|
}>): Promise<void>;
|
|
53
|
+
type DerivativesMetricCoverageMetric = 'liquidation';
|
|
54
|
+
declare function getDerivativesMetricCoverage(params: {
|
|
55
|
+
source: string;
|
|
56
|
+
metric: DerivativesMetricCoverageMetric;
|
|
57
|
+
symbols: string[];
|
|
58
|
+
interval: DerivativesInterval;
|
|
59
|
+
fromMs: number;
|
|
60
|
+
toMs: number;
|
|
61
|
+
}): Promise<{
|
|
62
|
+
symbol: string;
|
|
63
|
+
interval: DerivativesInterval;
|
|
64
|
+
fromMs: number;
|
|
65
|
+
toMs: number;
|
|
66
|
+
eventRowsCount: number;
|
|
67
|
+
zeroRowsCount: number;
|
|
68
|
+
}[]>;
|
|
69
|
+
declare function applyDerivativesMetricCoverage(rows: Array<{
|
|
70
|
+
source: string;
|
|
71
|
+
metric: DerivativesMetricCoverageMetric;
|
|
72
|
+
symbol: string;
|
|
73
|
+
interval: DerivativesInterval;
|
|
74
|
+
fromMs: number;
|
|
75
|
+
toMs: number;
|
|
76
|
+
eventRowsCount: number;
|
|
77
|
+
}>): Promise<{
|
|
78
|
+
symbol: string;
|
|
79
|
+
zeroRowsCount: number;
|
|
80
|
+
}[]>;
|
|
53
81
|
declare function getDerivativesWindow(params: {
|
|
54
82
|
symbol: string;
|
|
55
83
|
intervals: DerivativesInterval[];
|
|
@@ -271,4 +299,4 @@ declare function findContinuityGap(provider: string, symbol: string, interval: n
|
|
|
271
299
|
diffSeconds: number;
|
|
272
300
|
} | null>;
|
|
273
301
|
|
|
274
|
-
export { type CandleRow, type DeprecatedMarketContextCleanupItem, type MarketFeatureAsOf, cleanupDeprecatedMarketContext, closeTimescalePool, deleteCandles, findContinuityGap, getCandlesRange, getDataEdges, getDataEdgesForSymbols, getDerivativesBackfillCoverage, getDerivativesDataEdgesForSymbols, getDerivativesRangeForSymbols, getDerivativesSummary, getDerivativesWindow, getLatestMarketBreadth, getLatestMarketCmcExchangeLiquidityContext, getLatestMarketCmcFearGreedContext, getLatestMarketCmcIndexContexts, getLatestMarketGlobalContext, getLatestMarketReferenceAssetContexts, getLatestMarketTradeFlow, getMarketBreadthCoverage, getMarketCmcExchangeLiquidityContextCoverage, getMarketCmcFearGreedContextCoverage, getMarketCmcIndexContextCoverage, getMarketContextBackfillCoverage, getMarketGlobalContextCoverage, getMarketReferenceAssetContextCoverage, getMarketTradeFlowCoverage, getSpreadRangeForSymbols, getSpreadSummary, toRows, upsertCandles, upsertDerivatives, upsertDerivativesBackfillCoverage, upsertMarketBreadthRows, upsertMarketCmcExchangeLiquidityContextRows, upsertMarketCmcFearGreedContextRows, upsertMarketCmcIndexContextRows, upsertMarketContextBackfillCoverage, upsertMarketGlobalContextRows, upsertMarketReferenceAssetContextRows, upsertMarketTradeFlowRows, upsertSpreadRows, waitForDbReady };
|
|
302
|
+
export { type CandleRow, type DeprecatedMarketContextCleanupItem, type DerivativesMetricCoverageMetric, type MarketFeatureAsOf, applyDerivativesMetricCoverage, cleanupDeprecatedMarketContext, closeTimescalePool, deleteCandles, findContinuityGap, getCandlesRange, getDataEdges, getDataEdgesForSymbols, getDerivativesBackfillCoverage, getDerivativesDataEdgesForSymbols, getDerivativesMetricCoverage, getDerivativesRangeForSymbols, getDerivativesSummary, getDerivativesWindow, getLatestMarketBreadth, getLatestMarketCmcExchangeLiquidityContext, getLatestMarketCmcFearGreedContext, getLatestMarketCmcIndexContexts, getLatestMarketGlobalContext, getLatestMarketReferenceAssetContexts, getLatestMarketTradeFlow, getMarketBreadthCoverage, getMarketCmcExchangeLiquidityContextCoverage, getMarketCmcFearGreedContextCoverage, getMarketCmcIndexContextCoverage, getMarketContextBackfillCoverage, getMarketGlobalContextCoverage, getMarketReferenceAssetContextCoverage, getMarketTradeFlowCoverage, getSpreadRangeForSymbols, getSpreadSummary, toRows, upsertCandles, upsertDerivatives, upsertDerivativesBackfillCoverage, upsertMarketBreadthRows, upsertMarketCmcExchangeLiquidityContextRows, upsertMarketCmcFearGreedContextRows, upsertMarketCmcIndexContextRows, upsertMarketContextBackfillCoverage, upsertMarketGlobalContextRows, upsertMarketReferenceAssetContextRows, upsertMarketTradeFlowRows, upsertSpreadRows, waitForDbReady };
|
package/dist/timescale.js
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/timescale.ts
|
|
21
21
|
var timescale_exports = {};
|
|
22
22
|
__export(timescale_exports, {
|
|
23
|
+
applyDerivativesMetricCoverage: () => applyDerivativesMetricCoverage,
|
|
23
24
|
cleanupDeprecatedMarketContext: () => cleanupDeprecatedMarketContext,
|
|
24
25
|
closeTimescalePool: () => closeTimescalePool,
|
|
25
26
|
deleteCandles: () => deleteCandles,
|
|
@@ -29,6 +30,7 @@ __export(timescale_exports, {
|
|
|
29
30
|
getDataEdgesForSymbols: () => getDataEdgesForSymbols,
|
|
30
31
|
getDerivativesBackfillCoverage: () => getDerivativesBackfillCoverage,
|
|
31
32
|
getDerivativesDataEdgesForSymbols: () => getDerivativesDataEdgesForSymbols,
|
|
33
|
+
getDerivativesMetricCoverage: () => getDerivativesMetricCoverage,
|
|
32
34
|
getDerivativesRangeForSymbols: () => getDerivativesRangeForSymbols,
|
|
33
35
|
getDerivativesSummary: () => getDerivativesSummary,
|
|
34
36
|
getDerivativesWindow: () => getDerivativesWindow,
|
|
@@ -339,6 +341,31 @@ var ensureDerivativesSchema = async () => {
|
|
|
339
341
|
CREATE INDEX IF NOT EXISTS derivatives_backfill_coverage_lookup_idx
|
|
340
342
|
ON derivatives_backfill_coverage (source, symbol, interval, from_ts, to_ts)
|
|
341
343
|
`);
|
|
344
|
+
await pool.query(`
|
|
345
|
+
CREATE TABLE IF NOT EXISTS derivatives_metric_coverage (
|
|
346
|
+
source text NOT NULL,
|
|
347
|
+
metric text NOT NULL,
|
|
348
|
+
symbol text NOT NULL,
|
|
349
|
+
interval text NOT NULL,
|
|
350
|
+
from_ts timestamptz NOT NULL,
|
|
351
|
+
to_ts timestamptz NOT NULL,
|
|
352
|
+
event_rows_count integer NOT NULL DEFAULT 0,
|
|
353
|
+
zero_rows_count integer NOT NULL DEFAULT 0,
|
|
354
|
+
checked_at timestamptz NOT NULL DEFAULT now(),
|
|
355
|
+
PRIMARY KEY (source, metric, symbol, interval, from_ts, to_ts)
|
|
356
|
+
)
|
|
357
|
+
`);
|
|
358
|
+
await pool.query(`
|
|
359
|
+
CREATE INDEX IF NOT EXISTS derivatives_metric_coverage_lookup_idx
|
|
360
|
+
ON derivatives_metric_coverage (
|
|
361
|
+
source,
|
|
362
|
+
metric,
|
|
363
|
+
symbol,
|
|
364
|
+
interval,
|
|
365
|
+
from_ts,
|
|
366
|
+
to_ts
|
|
367
|
+
)
|
|
368
|
+
`);
|
|
342
369
|
derivativesSchemaReady = true;
|
|
343
370
|
}
|
|
344
371
|
).finally(() => {
|
|
@@ -849,6 +876,147 @@ async function upsertDerivativesBackfillCoverage(rows) {
|
|
|
849
876
|
flat
|
|
850
877
|
);
|
|
851
878
|
}
|
|
879
|
+
async function getDerivativesMetricCoverage(params) {
|
|
880
|
+
const normalizedSource = String(params.source || "").trim().toLowerCase();
|
|
881
|
+
const normalizedSymbols = [
|
|
882
|
+
...new Set(
|
|
883
|
+
params.symbols.map(
|
|
884
|
+
(symbol) => String(symbol || "").trim().toUpperCase()
|
|
885
|
+
).filter(Boolean)
|
|
886
|
+
)
|
|
887
|
+
];
|
|
888
|
+
if (!normalizedSource || !normalizedSymbols.length) {
|
|
889
|
+
return [];
|
|
890
|
+
}
|
|
891
|
+
await ensureDerivativesSchema();
|
|
892
|
+
const pool = getPool();
|
|
893
|
+
const res = await pool.query(
|
|
894
|
+
`
|
|
895
|
+
SELECT
|
|
896
|
+
symbol,
|
|
897
|
+
interval,
|
|
898
|
+
extract(epoch from from_ts)*1000 AS from_ms,
|
|
899
|
+
extract(epoch from to_ts)*1000 AS to_ms,
|
|
900
|
+
event_rows_count,
|
|
901
|
+
zero_rows_count
|
|
902
|
+
FROM derivatives_metric_coverage
|
|
903
|
+
WHERE source = $1
|
|
904
|
+
AND metric = $2
|
|
905
|
+
AND symbol = ANY($3)
|
|
906
|
+
AND interval = $4
|
|
907
|
+
AND from_ts <= to_timestamp($6/1000.0)
|
|
908
|
+
AND to_ts >= to_timestamp($5/1000.0)
|
|
909
|
+
`,
|
|
910
|
+
[
|
|
911
|
+
normalizedSource,
|
|
912
|
+
params.metric,
|
|
913
|
+
normalizedSymbols,
|
|
914
|
+
params.interval,
|
|
915
|
+
params.fromMs,
|
|
916
|
+
params.toMs
|
|
917
|
+
]
|
|
918
|
+
);
|
|
919
|
+
return res.rows.map((row) => ({
|
|
920
|
+
symbol: String(row.symbol).toUpperCase(),
|
|
921
|
+
interval: row.interval,
|
|
922
|
+
fromMs: Number(row.from_ms),
|
|
923
|
+
toMs: Number(row.to_ms),
|
|
924
|
+
eventRowsCount: Number(row.event_rows_count ?? 0),
|
|
925
|
+
zeroRowsCount: Number(row.zero_rows_count ?? 0)
|
|
926
|
+
}));
|
|
927
|
+
}
|
|
928
|
+
async function applyDerivativesMetricCoverage(rows) {
|
|
929
|
+
if (!rows.length)
|
|
930
|
+
return [];
|
|
931
|
+
await ensureDerivativesSchema();
|
|
932
|
+
const pool = getPool();
|
|
933
|
+
const client = await pool.connect();
|
|
934
|
+
const results = [];
|
|
935
|
+
try {
|
|
936
|
+
await client.query("BEGIN");
|
|
937
|
+
for (const row of rows) {
|
|
938
|
+
const source = String(row.source || "").trim().toLowerCase();
|
|
939
|
+
const symbol = String(row.symbol || "").trim().toUpperCase();
|
|
940
|
+
const fromMs = Math.trunc(row.fromMs);
|
|
941
|
+
const toMs = Math.trunc(row.toMs);
|
|
942
|
+
if (!source || !symbol || fromMs > toMs) continue;
|
|
943
|
+
await client.query(
|
|
944
|
+
`
|
|
945
|
+
UPDATE derivatives_market
|
|
946
|
+
SET
|
|
947
|
+
liq_long = 0,
|
|
948
|
+
liq_short = 0,
|
|
949
|
+
liq_total = 0,
|
|
950
|
+
ingested_at = now()
|
|
951
|
+
WHERE symbol = $1
|
|
952
|
+
AND interval = $2
|
|
953
|
+
AND ts >= to_timestamp($3/1000.0)
|
|
954
|
+
AND ts <= to_timestamp($4/1000.0)
|
|
955
|
+
AND liq_long IS NULL
|
|
956
|
+
AND liq_short IS NULL
|
|
957
|
+
AND liq_total IS NULL
|
|
958
|
+
`,
|
|
959
|
+
[symbol, row.interval, fromMs, toMs]
|
|
960
|
+
);
|
|
961
|
+
const zeroCountResult = await client.query(
|
|
962
|
+
`
|
|
963
|
+
SELECT COUNT(*)::integer AS count
|
|
964
|
+
FROM derivatives_market
|
|
965
|
+
WHERE symbol = $1
|
|
966
|
+
AND interval = $2
|
|
967
|
+
AND ts >= to_timestamp($3/1000.0)
|
|
968
|
+
AND ts <= to_timestamp($4/1000.0)
|
|
969
|
+
AND liq_long = 0
|
|
970
|
+
AND liq_short = 0
|
|
971
|
+
AND liq_total = 0
|
|
972
|
+
`,
|
|
973
|
+
[symbol, row.interval, fromMs, toMs]
|
|
974
|
+
);
|
|
975
|
+
const zeroRowsCount = Math.max(
|
|
976
|
+
0,
|
|
977
|
+
Number(zeroCountResult.rows[0]?.count ?? 0)
|
|
978
|
+
);
|
|
979
|
+
await client.query(
|
|
980
|
+
`
|
|
981
|
+
INSERT INTO derivatives_metric_coverage (
|
|
982
|
+
source,
|
|
983
|
+
metric,
|
|
984
|
+
symbol,
|
|
985
|
+
interval,
|
|
986
|
+
from_ts,
|
|
987
|
+
to_ts,
|
|
988
|
+
event_rows_count,
|
|
989
|
+
zero_rows_count
|
|
990
|
+
)
|
|
991
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
992
|
+
ON CONFLICT (source, metric, symbol, interval, from_ts, to_ts)
|
|
993
|
+
DO UPDATE SET
|
|
994
|
+
event_rows_count = EXCLUDED.event_rows_count,
|
|
995
|
+
zero_rows_count = EXCLUDED.zero_rows_count,
|
|
996
|
+
checked_at = now()
|
|
997
|
+
`,
|
|
998
|
+
[
|
|
999
|
+
source,
|
|
1000
|
+
row.metric,
|
|
1001
|
+
symbol,
|
|
1002
|
+
row.interval,
|
|
1003
|
+
new Date(fromMs),
|
|
1004
|
+
new Date(toMs),
|
|
1005
|
+
Math.max(0, Math.trunc(row.eventRowsCount)),
|
|
1006
|
+
zeroRowsCount
|
|
1007
|
+
]
|
|
1008
|
+
);
|
|
1009
|
+
results.push({ symbol, zeroRowsCount });
|
|
1010
|
+
}
|
|
1011
|
+
await client.query("COMMIT");
|
|
1012
|
+
return results;
|
|
1013
|
+
} catch (error) {
|
|
1014
|
+
await client.query("ROLLBACK");
|
|
1015
|
+
throw error;
|
|
1016
|
+
} finally {
|
|
1017
|
+
client.release();
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
852
1020
|
async function getDerivativesWindow(params) {
|
|
853
1021
|
const { symbol, intervals, endMs, lookbackMs } = params;
|
|
854
1022
|
const normalizedSymbol = String(symbol || "").trim().toUpperCase();
|
|
@@ -2502,6 +2670,7 @@ async function findContinuityGap(provider, symbol, interval) {
|
|
|
2502
2670
|
}
|
|
2503
2671
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2504
2672
|
0 && (module.exports = {
|
|
2673
|
+
applyDerivativesMetricCoverage,
|
|
2505
2674
|
cleanupDeprecatedMarketContext,
|
|
2506
2675
|
closeTimescalePool,
|
|
2507
2676
|
deleteCandles,
|
|
@@ -2511,6 +2680,7 @@ async function findContinuityGap(provider, symbol, interval) {
|
|
|
2511
2680
|
getDataEdgesForSymbols,
|
|
2512
2681
|
getDerivativesBackfillCoverage,
|
|
2513
2682
|
getDerivativesDataEdgesForSymbols,
|
|
2683
|
+
getDerivativesMetricCoverage,
|
|
2514
2684
|
getDerivativesRangeForSymbols,
|
|
2515
2685
|
getDerivativesSummary,
|
|
2516
2686
|
getDerivativesWindow,
|
package/dist/timescale.mjs
CHANGED
|
@@ -273,6 +273,31 @@ var ensureDerivativesSchema = async () => {
|
|
|
273
273
|
CREATE INDEX IF NOT EXISTS derivatives_backfill_coverage_lookup_idx
|
|
274
274
|
ON derivatives_backfill_coverage (source, symbol, interval, from_ts, to_ts)
|
|
275
275
|
`);
|
|
276
|
+
await pool.query(`
|
|
277
|
+
CREATE TABLE IF NOT EXISTS derivatives_metric_coverage (
|
|
278
|
+
source text NOT NULL,
|
|
279
|
+
metric text NOT NULL,
|
|
280
|
+
symbol text NOT NULL,
|
|
281
|
+
interval text NOT NULL,
|
|
282
|
+
from_ts timestamptz NOT NULL,
|
|
283
|
+
to_ts timestamptz NOT NULL,
|
|
284
|
+
event_rows_count integer NOT NULL DEFAULT 0,
|
|
285
|
+
zero_rows_count integer NOT NULL DEFAULT 0,
|
|
286
|
+
checked_at timestamptz NOT NULL DEFAULT now(),
|
|
287
|
+
PRIMARY KEY (source, metric, symbol, interval, from_ts, to_ts)
|
|
288
|
+
)
|
|
289
|
+
`);
|
|
290
|
+
await pool.query(`
|
|
291
|
+
CREATE INDEX IF NOT EXISTS derivatives_metric_coverage_lookup_idx
|
|
292
|
+
ON derivatives_metric_coverage (
|
|
293
|
+
source,
|
|
294
|
+
metric,
|
|
295
|
+
symbol,
|
|
296
|
+
interval,
|
|
297
|
+
from_ts,
|
|
298
|
+
to_ts
|
|
299
|
+
)
|
|
300
|
+
`);
|
|
276
301
|
derivativesSchemaReady = true;
|
|
277
302
|
}
|
|
278
303
|
).finally(() => {
|
|
@@ -783,6 +808,147 @@ async function upsertDerivativesBackfillCoverage(rows) {
|
|
|
783
808
|
flat
|
|
784
809
|
);
|
|
785
810
|
}
|
|
811
|
+
async function getDerivativesMetricCoverage(params) {
|
|
812
|
+
const normalizedSource = String(params.source || "").trim().toLowerCase();
|
|
813
|
+
const normalizedSymbols = [
|
|
814
|
+
...new Set(
|
|
815
|
+
params.symbols.map(
|
|
816
|
+
(symbol) => String(symbol || "").trim().toUpperCase()
|
|
817
|
+
).filter(Boolean)
|
|
818
|
+
)
|
|
819
|
+
];
|
|
820
|
+
if (!normalizedSource || !normalizedSymbols.length) {
|
|
821
|
+
return [];
|
|
822
|
+
}
|
|
823
|
+
await ensureDerivativesSchema();
|
|
824
|
+
const pool = getPool();
|
|
825
|
+
const res = await pool.query(
|
|
826
|
+
`
|
|
827
|
+
SELECT
|
|
828
|
+
symbol,
|
|
829
|
+
interval,
|
|
830
|
+
extract(epoch from from_ts)*1000 AS from_ms,
|
|
831
|
+
extract(epoch from to_ts)*1000 AS to_ms,
|
|
832
|
+
event_rows_count,
|
|
833
|
+
zero_rows_count
|
|
834
|
+
FROM derivatives_metric_coverage
|
|
835
|
+
WHERE source = $1
|
|
836
|
+
AND metric = $2
|
|
837
|
+
AND symbol = ANY($3)
|
|
838
|
+
AND interval = $4
|
|
839
|
+
AND from_ts <= to_timestamp($6/1000.0)
|
|
840
|
+
AND to_ts >= to_timestamp($5/1000.0)
|
|
841
|
+
`,
|
|
842
|
+
[
|
|
843
|
+
normalizedSource,
|
|
844
|
+
params.metric,
|
|
845
|
+
normalizedSymbols,
|
|
846
|
+
params.interval,
|
|
847
|
+
params.fromMs,
|
|
848
|
+
params.toMs
|
|
849
|
+
]
|
|
850
|
+
);
|
|
851
|
+
return res.rows.map((row) => ({
|
|
852
|
+
symbol: String(row.symbol).toUpperCase(),
|
|
853
|
+
interval: row.interval,
|
|
854
|
+
fromMs: Number(row.from_ms),
|
|
855
|
+
toMs: Number(row.to_ms),
|
|
856
|
+
eventRowsCount: Number(row.event_rows_count ?? 0),
|
|
857
|
+
zeroRowsCount: Number(row.zero_rows_count ?? 0)
|
|
858
|
+
}));
|
|
859
|
+
}
|
|
860
|
+
async function applyDerivativesMetricCoverage(rows) {
|
|
861
|
+
if (!rows.length)
|
|
862
|
+
return [];
|
|
863
|
+
await ensureDerivativesSchema();
|
|
864
|
+
const pool = getPool();
|
|
865
|
+
const client = await pool.connect();
|
|
866
|
+
const results = [];
|
|
867
|
+
try {
|
|
868
|
+
await client.query("BEGIN");
|
|
869
|
+
for (const row of rows) {
|
|
870
|
+
const source = String(row.source || "").trim().toLowerCase();
|
|
871
|
+
const symbol = String(row.symbol || "").trim().toUpperCase();
|
|
872
|
+
const fromMs = Math.trunc(row.fromMs);
|
|
873
|
+
const toMs = Math.trunc(row.toMs);
|
|
874
|
+
if (!source || !symbol || fromMs > toMs) continue;
|
|
875
|
+
await client.query(
|
|
876
|
+
`
|
|
877
|
+
UPDATE derivatives_market
|
|
878
|
+
SET
|
|
879
|
+
liq_long = 0,
|
|
880
|
+
liq_short = 0,
|
|
881
|
+
liq_total = 0,
|
|
882
|
+
ingested_at = now()
|
|
883
|
+
WHERE symbol = $1
|
|
884
|
+
AND interval = $2
|
|
885
|
+
AND ts >= to_timestamp($3/1000.0)
|
|
886
|
+
AND ts <= to_timestamp($4/1000.0)
|
|
887
|
+
AND liq_long IS NULL
|
|
888
|
+
AND liq_short IS NULL
|
|
889
|
+
AND liq_total IS NULL
|
|
890
|
+
`,
|
|
891
|
+
[symbol, row.interval, fromMs, toMs]
|
|
892
|
+
);
|
|
893
|
+
const zeroCountResult = await client.query(
|
|
894
|
+
`
|
|
895
|
+
SELECT COUNT(*)::integer AS count
|
|
896
|
+
FROM derivatives_market
|
|
897
|
+
WHERE symbol = $1
|
|
898
|
+
AND interval = $2
|
|
899
|
+
AND ts >= to_timestamp($3/1000.0)
|
|
900
|
+
AND ts <= to_timestamp($4/1000.0)
|
|
901
|
+
AND liq_long = 0
|
|
902
|
+
AND liq_short = 0
|
|
903
|
+
AND liq_total = 0
|
|
904
|
+
`,
|
|
905
|
+
[symbol, row.interval, fromMs, toMs]
|
|
906
|
+
);
|
|
907
|
+
const zeroRowsCount = Math.max(
|
|
908
|
+
0,
|
|
909
|
+
Number(zeroCountResult.rows[0]?.count ?? 0)
|
|
910
|
+
);
|
|
911
|
+
await client.query(
|
|
912
|
+
`
|
|
913
|
+
INSERT INTO derivatives_metric_coverage (
|
|
914
|
+
source,
|
|
915
|
+
metric,
|
|
916
|
+
symbol,
|
|
917
|
+
interval,
|
|
918
|
+
from_ts,
|
|
919
|
+
to_ts,
|
|
920
|
+
event_rows_count,
|
|
921
|
+
zero_rows_count
|
|
922
|
+
)
|
|
923
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
924
|
+
ON CONFLICT (source, metric, symbol, interval, from_ts, to_ts)
|
|
925
|
+
DO UPDATE SET
|
|
926
|
+
event_rows_count = EXCLUDED.event_rows_count,
|
|
927
|
+
zero_rows_count = EXCLUDED.zero_rows_count,
|
|
928
|
+
checked_at = now()
|
|
929
|
+
`,
|
|
930
|
+
[
|
|
931
|
+
source,
|
|
932
|
+
row.metric,
|
|
933
|
+
symbol,
|
|
934
|
+
row.interval,
|
|
935
|
+
new Date(fromMs),
|
|
936
|
+
new Date(toMs),
|
|
937
|
+
Math.max(0, Math.trunc(row.eventRowsCount)),
|
|
938
|
+
zeroRowsCount
|
|
939
|
+
]
|
|
940
|
+
);
|
|
941
|
+
results.push({ symbol, zeroRowsCount });
|
|
942
|
+
}
|
|
943
|
+
await client.query("COMMIT");
|
|
944
|
+
return results;
|
|
945
|
+
} catch (error) {
|
|
946
|
+
await client.query("ROLLBACK");
|
|
947
|
+
throw error;
|
|
948
|
+
} finally {
|
|
949
|
+
client.release();
|
|
950
|
+
}
|
|
951
|
+
}
|
|
786
952
|
async function getDerivativesWindow(params) {
|
|
787
953
|
const { symbol, intervals, endMs, lookbackMs } = params;
|
|
788
954
|
const normalizedSymbol = String(symbol || "").trim().toUpperCase();
|
|
@@ -2435,6 +2601,7 @@ async function findContinuityGap(provider, symbol, interval) {
|
|
|
2435
2601
|
};
|
|
2436
2602
|
}
|
|
2437
2603
|
export {
|
|
2604
|
+
applyDerivativesMetricCoverage,
|
|
2438
2605
|
cleanupDeprecatedMarketContext,
|
|
2439
2606
|
closeTimescalePool,
|
|
2440
2607
|
deleteCandles,
|
|
@@ -2444,6 +2611,7 @@ export {
|
|
|
2444
2611
|
getDataEdgesForSymbols,
|
|
2445
2612
|
getDerivativesBackfillCoverage,
|
|
2446
2613
|
getDerivativesDataEdgesForSymbols,
|
|
2614
|
+
getDerivativesMetricCoverage,
|
|
2447
2615
|
getDerivativesRangeForSymbols,
|
|
2448
2616
|
getDerivativesSummary,
|
|
2449
2617
|
getDerivativesWindow,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tradejs/infra",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "MIT-licensed server infrastructure adapters for TradeJS: Redis, Timescale, ML, logging, and IO.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tradejs",
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"dependencies": {
|
|
94
94
|
"@grpc/grpc-js": "^1.10.7",
|
|
95
95
|
"@grpc/proto-loader": "^0.8.0",
|
|
96
|
-
"@tradejs/types": "^2.0.
|
|
96
|
+
"@tradejs/types": "^2.0.2",
|
|
97
97
|
"chalk": "4.1.2",
|
|
98
98
|
"ioredis": "5.8.0",
|
|
99
99
|
"pg": "8.16.3",
|