@tradejs/core 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.
@@ -130,6 +130,32 @@ var toFiniteNumber = (value, fallback = 0) => {
130
130
  };
131
131
 
132
132
  // src/utils/derivativesCoinalyze.ts
133
+ var DERIVATIVES_INTERVAL_MS = {
134
+ "15m": 15 * 60 * 1e3,
135
+ "1h": 60 * 60 * 1e3
136
+ };
137
+ var COINALYZE_MIN_INTRADAY_RETENTION_POINTS = 1500;
138
+ var getLastClosedDerivativesBarStartMs = (timestamp, interval) => {
139
+ const intervalMs = DERIVATIVES_INTERVAL_MS[interval];
140
+ return Math.floor(timestamp / intervalMs) * intervalMs - intervalMs;
141
+ };
142
+ var resolveCoinalyzeConfirmedIntradayCoverage = (params) => {
143
+ const intervalMs = DERIVATIVES_INTERVAL_MS[params.interval];
144
+ const nowMs = params.nowMs ?? Date.now();
145
+ const lastClosedStartMs = getLastClosedDerivativesBarStartMs(
146
+ nowMs,
147
+ params.interval
148
+ );
149
+ const guaranteedRetentionFromMs = lastClosedStartMs - (COINALYZE_MIN_INTRADAY_RETENTION_POINTS - 1) * intervalMs;
150
+ const requestedFromMs = Math.ceil(params.fromMs / intervalMs) * intervalMs;
151
+ const requestedToMs = Math.floor(params.toMs / intervalMs) * intervalMs;
152
+ const fromMs = Math.max(requestedFromMs, guaranteedRetentionFromMs);
153
+ const toMs2 = Math.min(requestedToMs, lastClosedStartMs);
154
+ return fromMs <= toMs2 ? {
155
+ fromMs,
156
+ toMs: toMs2
157
+ } : null;
158
+ };
133
159
  var normalizeCoinalyzeSymbols = (input) => String(input ?? "").split(",").map((item) => item.trim().toUpperCase()).filter(Boolean);
134
160
  var normalizeDerivativesIntervals = (input) => parseDerivativesIntervals(input);
135
161
  var toCoinalyzeTimestampMs = (value) => {
@@ -210,6 +236,103 @@ var coinalyzePointsToRows = (points, interval, source) => points.map((point) =>
210
236
  liqTotal: point.liqTotal ?? null,
211
237
  source
212
238
  }));
239
+ var sumAvailable = (values) => {
240
+ const available = values.filter(
241
+ (value) => typeof value === "number" && Number.isFinite(value)
242
+ );
243
+ return available.length ? available.reduce((total, value) => total + value, 0) : null;
244
+ };
245
+ var getLiquidationTotal = (row) => typeof row.liqTotal === "number" && Number.isFinite(row.liqTotal) ? row.liqTotal : sumAvailable([row.liqLong, row.liqShort]);
246
+ var deriveCoinalyzeHourlyRowsFrom15m = (rows) => {
247
+ const quarterHourMs = DERIVATIVES_INTERVAL_MS["15m"];
248
+ const hourMs = DERIVATIVES_INTERVAL_MS["1h"];
249
+ const rowsByHour = /* @__PURE__ */ new Map();
250
+ for (const row of rows ?? []) {
251
+ if (row.interval !== "15m") continue;
252
+ const timestamp = row.ts.getTime();
253
+ if (!Number.isFinite(timestamp) || timestamp % quarterHourMs !== 0) {
254
+ continue;
255
+ }
256
+ const hourStart = Math.floor(timestamp / hourMs) * hourMs;
257
+ const hourRows = rowsByHour.get(hourStart) ?? /* @__PURE__ */ new Map();
258
+ hourRows.set(timestamp, row);
259
+ rowsByHour.set(hourStart, hourRows);
260
+ }
261
+ const hourlyRows = [];
262
+ for (const [hourStart, hourRows] of [...rowsByHour.entries()].sort(
263
+ ([left], [right]) => left - right
264
+ )) {
265
+ const expectedRows = [0, 1, 2, 3].map(
266
+ (offset) => hourRows.get(hourStart + offset * quarterHourMs)
267
+ );
268
+ if (expectedRows.some((row) => row == null)) continue;
269
+ const completeRows = expectedRows;
270
+ const latest = completeRows[completeRows.length - 1];
271
+ hourlyRows.push({
272
+ symbol: latest.symbol,
273
+ interval: "1h",
274
+ ts: new Date(hourStart),
275
+ openInterest: latest.openInterest ?? null,
276
+ fundingRate: latest.fundingRate ?? null,
277
+ liqLong: sumAvailable(completeRows.map((row) => row.liqLong)),
278
+ liqShort: sumAvailable(completeRows.map((row) => row.liqShort)),
279
+ liqTotal: sumAvailable(completeRows.map(getLiquidationTotal)),
280
+ source: latest.source ?? null
281
+ });
282
+ }
283
+ return hourlyRows;
284
+ };
285
+ var deriveCoinalyzeRollingHourlyRowsFrom15m = (rows) => {
286
+ const quarterHourMs = DERIVATIVES_INTERVAL_MS["15m"];
287
+ const rowsByTimestamp = /* @__PURE__ */ new Map();
288
+ for (const row of rows ?? []) {
289
+ const timestamp = row.ts.getTime();
290
+ if (row.interval !== "15m" || !Number.isFinite(timestamp) || timestamp % quarterHourMs !== 0) {
291
+ continue;
292
+ }
293
+ rowsByTimestamp.set(timestamp, row);
294
+ }
295
+ const rollingRows = [];
296
+ for (const timestamp of [...rowsByTimestamp.keys()].sort(
297
+ (left, right) => left - right
298
+ )) {
299
+ const expectedRows = [3, 2, 1, 0].map(
300
+ (offset) => rowsByTimestamp.get(timestamp - offset * quarterHourMs)
301
+ );
302
+ if (expectedRows.some((row) => row == null)) continue;
303
+ const completeRows = expectedRows;
304
+ const latest = completeRows[completeRows.length - 1];
305
+ rollingRows.push({
306
+ symbol: latest.symbol,
307
+ interval: "1h",
308
+ ts: new Date(timestamp),
309
+ openInterest: latest.openInterest ?? null,
310
+ fundingRate: latest.fundingRate ?? null,
311
+ liqLong: sumAvailable(completeRows.map((row) => row.liqLong)),
312
+ liqShort: sumAvailable(completeRows.map((row) => row.liqShort)),
313
+ liqTotal: sumAvailable(completeRows.map(getLiquidationTotal)),
314
+ source: `${latest.source ?? "coinalyze"}:rolling_15m`
315
+ });
316
+ }
317
+ return rollingRows;
318
+ };
319
+ var buildCoinalyzeHourlyRowsWithFallback = (params) => {
320
+ const hourMs = DERIVATIVES_INTERVAL_MS["1h"];
321
+ const rollingRows = deriveCoinalyzeRollingHourlyRowsFrom15m(params.rows15m);
322
+ const rollingHours = new Set(
323
+ rollingRows.map((row) => Math.floor(row.ts.getTime() / hourMs) * hourMs)
324
+ );
325
+ const fallbackRows = (params.fallbackRows1h ?? []).filter((row) => {
326
+ const timestamp = row.ts.getTime();
327
+ return row.interval === "1h" && Number.isFinite(timestamp) && timestamp % hourMs === 0 && !rollingHours.has(timestamp);
328
+ }).map((row) => ({
329
+ ...row,
330
+ source: `${row.source ?? "coinalyze"}:legacy_1h_fallback`
331
+ }));
332
+ return [...fallbackRows, ...rollingRows].sort(
333
+ (left, right) => left.ts.getTime() - right.ts.getTime()
334
+ );
335
+ };
213
336
 
214
337
  // src/utils/derivativesContext.ts
215
338
  var HOUR_MS = 60 * 60 * 1e3;
@@ -11814,6 +11937,9 @@ export {
11814
11937
  buildReturnsFromCandles,
11815
11938
  calculatePearsonCorrelation,
11816
11939
  calculateCoinBtcCorrelation,
11940
+ COINALYZE_MIN_INTRADAY_RETENTION_POINTS,
11941
+ getLastClosedDerivativesBarStartMs,
11942
+ resolveCoinalyzeConfirmedIntradayCoverage,
11817
11943
  normalizeCoinalyzeSymbols,
11818
11944
  normalizeDerivativesIntervals,
11819
11945
  toCoinalyzeTimestampMs,
@@ -11821,6 +11947,9 @@ export {
11821
11947
  toArrayData,
11822
11948
  mergeCoinalyzeMetrics,
11823
11949
  coinalyzePointsToRows,
11950
+ deriveCoinalyzeHourlyRowsFrom15m,
11951
+ deriveCoinalyzeRollingHourlyRowsFrom15m,
11952
+ buildCoinalyzeHourlyRowsWithFallback,
11824
11953
  buildDerivativesContext,
11825
11954
  buildMlCandleIndicators,
11826
11955
  registerIndicatorEntries,
@@ -1,4 +1,4 @@
1
- import { KlineChartItem, DerivativesInterval, DerivativesRow, Direction, DerivativesContext, IndicatorPluginRenderer, Indicator, IndicatorPluginEntry, TrendLine, TrendLineOptions } from '@tradejs/types';
1
+ import { KlineChartItem, DerivativesRow, DerivativesInterval, Direction, DerivativesContext, IndicatorPluginRenderer, Indicator, IndicatorPluginEntry, TrendLine, TrendLineOptions } from '@tradejs/types';
2
2
  export { C as COMPACT_INDICATORS_SNAPSHOT_KEY, c as COMPACT_INDICATORS_SNAPSHOT_SYMBOL, I as IndicatorPeriods, b as IndicatorsControllerCheckpointState, a as IndicatorsControllerRuntimeState, P as PricePoint, S as SpreadSmootherState, d as alignSpreadRows, e as applyIndicatorsToHistory, f as buildMlCandleIndicators, g as buildMlTimeframeIndicators, h as coinbaseProductFromSymbol, i as createIndicators, j as createSerializableSpreadSmoother, k as createSpreadSmoother, l as getRequiredControllerSeedWindow, m as intervalToMs, r as rollingMeanStd, s as smoothSpreadSeries } from './indicators-Da_i06-8.mjs';
3
3
  import { KLineData } from 'klinecharts';
4
4
 
@@ -37,6 +37,17 @@ type CoinalyzePoint = {
37
37
  liqShort?: number | null;
38
38
  liqTotal?: number | null;
39
39
  };
40
+ declare const COINALYZE_MIN_INTRADAY_RETENTION_POINTS = 1500;
41
+ declare const getLastClosedDerivativesBarStartMs: (timestamp: number, interval: DerivativesInterval) => number;
42
+ declare const resolveCoinalyzeConfirmedIntradayCoverage: (params: {
43
+ interval: DerivativesInterval;
44
+ fromMs: number;
45
+ toMs: number;
46
+ nowMs?: number;
47
+ }) => {
48
+ fromMs: number;
49
+ toMs: number;
50
+ } | null;
40
51
  declare const normalizeCoinalyzeSymbols: (input: unknown) => string[];
41
52
  declare const normalizeDerivativesIntervals: (input: unknown) => DerivativesInterval[];
42
53
  declare const toCoinalyzeTimestampMs: (value: unknown) => number | null;
@@ -49,6 +60,12 @@ declare const mergeCoinalyzeMetrics: (params: {
49
60
  liqRaw: unknown;
50
61
  }) => CoinalyzePoint[];
51
62
  declare const coinalyzePointsToRows: (points: CoinalyzePoint[], interval: DerivativesInterval, source: string) => DerivativesRow[];
63
+ declare const deriveCoinalyzeHourlyRowsFrom15m: (rows: DerivativesRow[] | undefined) => DerivativesRow[];
64
+ declare const deriveCoinalyzeRollingHourlyRowsFrom15m: (rows: DerivativesRow[] | undefined) => DerivativesRow[];
65
+ declare const buildCoinalyzeHourlyRowsWithFallback: (params: {
66
+ rows15m: DerivativesRow[] | undefined;
67
+ fallbackRows1h: DerivativesRow[] | undefined;
68
+ }) => DerivativesRow[];
52
69
 
53
70
  declare const buildDerivativesContext: (params: {
54
71
  symbol: string;
@@ -93,4 +110,4 @@ type TrendlineEngine = {
93
110
  };
94
111
  declare const createTrendlineEngine: (initialCandles: KLineData[], options: TrendLineOptions) => TrendlineEngine;
95
112
 
96
- export { type CoinalyzePoint, type IndicatorRendererDescriptor, type TrendlineEngine, alignSortedCandlesByTimestamp, buildDerivativesContext, buildReturnsFromCandles, calculateCoinBtcCorrelation, calculatePearsonCorrelation, coinalyzePointsToRows, createTrendlineEngine, detectRawSupportResistance, getPluginIndicatorCatalog, getPluginIndicatorRenderers, getRegisteredIndicatorEntries, getSupportResistanceLevels, mergeCoinalyzeMetrics, normalizeCoinalyzeSymbols, normalizeDerivativesIntervals, registerIndicatorEntries, resetIndicatorRegistryCache, toArrayData, toCoinalyzeTimestampMs, toFiniteNumber };
113
+ export { COINALYZE_MIN_INTRADAY_RETENTION_POINTS, type CoinalyzePoint, type IndicatorRendererDescriptor, type TrendlineEngine, alignSortedCandlesByTimestamp, buildCoinalyzeHourlyRowsWithFallback, buildDerivativesContext, buildReturnsFromCandles, calculateCoinBtcCorrelation, calculatePearsonCorrelation, coinalyzePointsToRows, createTrendlineEngine, deriveCoinalyzeHourlyRowsFrom15m, deriveCoinalyzeRollingHourlyRowsFrom15m, detectRawSupportResistance, getLastClosedDerivativesBarStartMs, getPluginIndicatorCatalog, getPluginIndicatorRenderers, getRegisteredIndicatorEntries, getSupportResistanceLevels, mergeCoinalyzeMetrics, normalizeCoinalyzeSymbols, normalizeDerivativesIntervals, registerIndicatorEntries, resetIndicatorRegistryCache, resolveCoinalyzeConfirmedIntradayCoverage, toArrayData, toCoinalyzeTimestampMs, toFiniteNumber };
@@ -1,4 +1,4 @@
1
- import { KlineChartItem, DerivativesInterval, DerivativesRow, Direction, DerivativesContext, IndicatorPluginRenderer, Indicator, IndicatorPluginEntry, TrendLine, TrendLineOptions } from '@tradejs/types';
1
+ import { KlineChartItem, DerivativesRow, DerivativesInterval, Direction, DerivativesContext, IndicatorPluginRenderer, Indicator, IndicatorPluginEntry, TrendLine, TrendLineOptions } from '@tradejs/types';
2
2
  export { C as COMPACT_INDICATORS_SNAPSHOT_KEY, c as COMPACT_INDICATORS_SNAPSHOT_SYMBOL, I as IndicatorPeriods, b as IndicatorsControllerCheckpointState, a as IndicatorsControllerRuntimeState, P as PricePoint, S as SpreadSmootherState, d as alignSpreadRows, e as applyIndicatorsToHistory, f as buildMlCandleIndicators, g as buildMlTimeframeIndicators, h as coinbaseProductFromSymbol, i as createIndicators, j as createSerializableSpreadSmoother, k as createSpreadSmoother, l as getRequiredControllerSeedWindow, m as intervalToMs, r as rollingMeanStd, s as smoothSpreadSeries } from './indicators-Da_i06-8.js';
3
3
  import { KLineData } from 'klinecharts';
4
4
 
@@ -37,6 +37,17 @@ type CoinalyzePoint = {
37
37
  liqShort?: number | null;
38
38
  liqTotal?: number | null;
39
39
  };
40
+ declare const COINALYZE_MIN_INTRADAY_RETENTION_POINTS = 1500;
41
+ declare const getLastClosedDerivativesBarStartMs: (timestamp: number, interval: DerivativesInterval) => number;
42
+ declare const resolveCoinalyzeConfirmedIntradayCoverage: (params: {
43
+ interval: DerivativesInterval;
44
+ fromMs: number;
45
+ toMs: number;
46
+ nowMs?: number;
47
+ }) => {
48
+ fromMs: number;
49
+ toMs: number;
50
+ } | null;
40
51
  declare const normalizeCoinalyzeSymbols: (input: unknown) => string[];
41
52
  declare const normalizeDerivativesIntervals: (input: unknown) => DerivativesInterval[];
42
53
  declare const toCoinalyzeTimestampMs: (value: unknown) => number | null;
@@ -49,6 +60,12 @@ declare const mergeCoinalyzeMetrics: (params: {
49
60
  liqRaw: unknown;
50
61
  }) => CoinalyzePoint[];
51
62
  declare const coinalyzePointsToRows: (points: CoinalyzePoint[], interval: DerivativesInterval, source: string) => DerivativesRow[];
63
+ declare const deriveCoinalyzeHourlyRowsFrom15m: (rows: DerivativesRow[] | undefined) => DerivativesRow[];
64
+ declare const deriveCoinalyzeRollingHourlyRowsFrom15m: (rows: DerivativesRow[] | undefined) => DerivativesRow[];
65
+ declare const buildCoinalyzeHourlyRowsWithFallback: (params: {
66
+ rows15m: DerivativesRow[] | undefined;
67
+ fallbackRows1h: DerivativesRow[] | undefined;
68
+ }) => DerivativesRow[];
52
69
 
53
70
  declare const buildDerivativesContext: (params: {
54
71
  symbol: string;
@@ -93,4 +110,4 @@ type TrendlineEngine = {
93
110
  };
94
111
  declare const createTrendlineEngine: (initialCandles: KLineData[], options: TrendLineOptions) => TrendlineEngine;
95
112
 
96
- export { type CoinalyzePoint, type IndicatorRendererDescriptor, type TrendlineEngine, alignSortedCandlesByTimestamp, buildDerivativesContext, buildReturnsFromCandles, calculateCoinBtcCorrelation, calculatePearsonCorrelation, coinalyzePointsToRows, createTrendlineEngine, detectRawSupportResistance, getPluginIndicatorCatalog, getPluginIndicatorRenderers, getRegisteredIndicatorEntries, getSupportResistanceLevels, mergeCoinalyzeMetrics, normalizeCoinalyzeSymbols, normalizeDerivativesIntervals, registerIndicatorEntries, resetIndicatorRegistryCache, toArrayData, toCoinalyzeTimestampMs, toFiniteNumber };
113
+ export { COINALYZE_MIN_INTRADAY_RETENTION_POINTS, type CoinalyzePoint, type IndicatorRendererDescriptor, type TrendlineEngine, alignSortedCandlesByTimestamp, buildCoinalyzeHourlyRowsWithFallback, buildDerivativesContext, buildReturnsFromCandles, calculateCoinBtcCorrelation, calculatePearsonCorrelation, coinalyzePointsToRows, createTrendlineEngine, deriveCoinalyzeHourlyRowsFrom15m, deriveCoinalyzeRollingHourlyRowsFrom15m, detectRawSupportResistance, getLastClosedDerivativesBarStartMs, getPluginIndicatorCatalog, getPluginIndicatorRenderers, getRegisteredIndicatorEntries, getSupportResistanceLevels, mergeCoinalyzeMetrics, normalizeCoinalyzeSymbols, normalizeDerivativesIntervals, registerIndicatorEntries, resetIndicatorRegistryCache, resolveCoinalyzeConfirmedIntradayCoverage, toArrayData, toCoinalyzeTimestampMs, toFiniteNumber };
@@ -30,11 +30,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/indicators.ts
31
31
  var indicators_exports = {};
32
32
  __export(indicators_exports, {
33
+ COINALYZE_MIN_INTRADAY_RETENTION_POINTS: () => COINALYZE_MIN_INTRADAY_RETENTION_POINTS,
33
34
  COMPACT_INDICATORS_SNAPSHOT_KEY: () => COMPACT_INDICATORS_SNAPSHOT_KEY,
34
35
  COMPACT_INDICATORS_SNAPSHOT_SYMBOL: () => COMPACT_INDICATORS_SNAPSHOT_SYMBOL,
35
36
  alignSortedCandlesByTimestamp: () => alignSortedCandlesByTimestamp,
36
37
  alignSpreadRows: () => alignSpreadRows,
37
38
  applyIndicatorsToHistory: () => applyIndicatorsToHistory,
39
+ buildCoinalyzeHourlyRowsWithFallback: () => buildCoinalyzeHourlyRowsWithFallback,
38
40
  buildDerivativesContext: () => buildDerivativesContext,
39
41
  buildMlCandleIndicators: () => buildMlCandleIndicators,
40
42
  buildMlTimeframeIndicators: () => buildMlTimeframeIndicators,
@@ -47,7 +49,10 @@ __export(indicators_exports, {
47
49
  createSerializableSpreadSmoother: () => createSerializableSpreadSmoother,
48
50
  createSpreadSmoother: () => createSpreadSmoother,
49
51
  createTrendlineEngine: () => createTrendlineEngine,
52
+ deriveCoinalyzeHourlyRowsFrom15m: () => deriveCoinalyzeHourlyRowsFrom15m,
53
+ deriveCoinalyzeRollingHourlyRowsFrom15m: () => deriveCoinalyzeRollingHourlyRowsFrom15m,
50
54
  detectRawSupportResistance: () => detectRawSupportResistance,
55
+ getLastClosedDerivativesBarStartMs: () => getLastClosedDerivativesBarStartMs,
51
56
  getPluginIndicatorCatalog: () => getPluginIndicatorCatalog,
52
57
  getPluginIndicatorRenderers: () => getPluginIndicatorRenderers,
53
58
  getRegisteredIndicatorEntries: () => getRegisteredIndicatorEntries,
@@ -59,6 +64,7 @@ __export(indicators_exports, {
59
64
  normalizeDerivativesIntervals: () => normalizeDerivativesIntervals,
60
65
  registerIndicatorEntries: () => registerIndicatorEntries,
61
66
  resetIndicatorRegistryCache: () => resetIndicatorRegistryCache,
67
+ resolveCoinalyzeConfirmedIntradayCoverage: () => resolveCoinalyzeConfirmedIntradayCoverage,
62
68
  rollingMeanStd: () => rollingMeanStd,
63
69
  smoothSpreadSeries: () => smoothSpreadSeries,
64
70
  toArrayData: () => toArrayData,
@@ -188,6 +194,32 @@ var toFiniteNumber = (value, fallback = 0) => {
188
194
  };
189
195
 
190
196
  // src/utils/derivativesCoinalyze.ts
197
+ var DERIVATIVES_INTERVAL_MS = {
198
+ "15m": 15 * 60 * 1e3,
199
+ "1h": 60 * 60 * 1e3
200
+ };
201
+ var COINALYZE_MIN_INTRADAY_RETENTION_POINTS = 1500;
202
+ var getLastClosedDerivativesBarStartMs = (timestamp, interval) => {
203
+ const intervalMs = DERIVATIVES_INTERVAL_MS[interval];
204
+ return Math.floor(timestamp / intervalMs) * intervalMs - intervalMs;
205
+ };
206
+ var resolveCoinalyzeConfirmedIntradayCoverage = (params) => {
207
+ const intervalMs = DERIVATIVES_INTERVAL_MS[params.interval];
208
+ const nowMs = params.nowMs ?? Date.now();
209
+ const lastClosedStartMs = getLastClosedDerivativesBarStartMs(
210
+ nowMs,
211
+ params.interval
212
+ );
213
+ const guaranteedRetentionFromMs = lastClosedStartMs - (COINALYZE_MIN_INTRADAY_RETENTION_POINTS - 1) * intervalMs;
214
+ const requestedFromMs = Math.ceil(params.fromMs / intervalMs) * intervalMs;
215
+ const requestedToMs = Math.floor(params.toMs / intervalMs) * intervalMs;
216
+ const fromMs = Math.max(requestedFromMs, guaranteedRetentionFromMs);
217
+ const toMs2 = Math.min(requestedToMs, lastClosedStartMs);
218
+ return fromMs <= toMs2 ? {
219
+ fromMs,
220
+ toMs: toMs2
221
+ } : null;
222
+ };
191
223
  var normalizeCoinalyzeSymbols = (input) => String(input ?? "").split(",").map((item) => item.trim().toUpperCase()).filter(Boolean);
192
224
  var normalizeDerivativesIntervals = (input) => parseDerivativesIntervals(input);
193
225
  var toCoinalyzeTimestampMs = (value) => {
@@ -268,6 +300,103 @@ var coinalyzePointsToRows = (points, interval, source) => points.map((point) =>
268
300
  liqTotal: point.liqTotal ?? null,
269
301
  source
270
302
  }));
303
+ var sumAvailable = (values) => {
304
+ const available = values.filter(
305
+ (value) => typeof value === "number" && Number.isFinite(value)
306
+ );
307
+ return available.length ? available.reduce((total, value) => total + value, 0) : null;
308
+ };
309
+ var getLiquidationTotal = (row) => typeof row.liqTotal === "number" && Number.isFinite(row.liqTotal) ? row.liqTotal : sumAvailable([row.liqLong, row.liqShort]);
310
+ var deriveCoinalyzeHourlyRowsFrom15m = (rows) => {
311
+ const quarterHourMs = DERIVATIVES_INTERVAL_MS["15m"];
312
+ const hourMs = DERIVATIVES_INTERVAL_MS["1h"];
313
+ const rowsByHour = /* @__PURE__ */ new Map();
314
+ for (const row of rows ?? []) {
315
+ if (row.interval !== "15m") continue;
316
+ const timestamp = row.ts.getTime();
317
+ if (!Number.isFinite(timestamp) || timestamp % quarterHourMs !== 0) {
318
+ continue;
319
+ }
320
+ const hourStart = Math.floor(timestamp / hourMs) * hourMs;
321
+ const hourRows = rowsByHour.get(hourStart) ?? /* @__PURE__ */ new Map();
322
+ hourRows.set(timestamp, row);
323
+ rowsByHour.set(hourStart, hourRows);
324
+ }
325
+ const hourlyRows = [];
326
+ for (const [hourStart, hourRows] of [...rowsByHour.entries()].sort(
327
+ ([left], [right]) => left - right
328
+ )) {
329
+ const expectedRows = [0, 1, 2, 3].map(
330
+ (offset) => hourRows.get(hourStart + offset * quarterHourMs)
331
+ );
332
+ if (expectedRows.some((row) => row == null)) continue;
333
+ const completeRows = expectedRows;
334
+ const latest = completeRows[completeRows.length - 1];
335
+ hourlyRows.push({
336
+ symbol: latest.symbol,
337
+ interval: "1h",
338
+ ts: new Date(hourStart),
339
+ openInterest: latest.openInterest ?? null,
340
+ fundingRate: latest.fundingRate ?? null,
341
+ liqLong: sumAvailable(completeRows.map((row) => row.liqLong)),
342
+ liqShort: sumAvailable(completeRows.map((row) => row.liqShort)),
343
+ liqTotal: sumAvailable(completeRows.map(getLiquidationTotal)),
344
+ source: latest.source ?? null
345
+ });
346
+ }
347
+ return hourlyRows;
348
+ };
349
+ var deriveCoinalyzeRollingHourlyRowsFrom15m = (rows) => {
350
+ const quarterHourMs = DERIVATIVES_INTERVAL_MS["15m"];
351
+ const rowsByTimestamp = /* @__PURE__ */ new Map();
352
+ for (const row of rows ?? []) {
353
+ const timestamp = row.ts.getTime();
354
+ if (row.interval !== "15m" || !Number.isFinite(timestamp) || timestamp % quarterHourMs !== 0) {
355
+ continue;
356
+ }
357
+ rowsByTimestamp.set(timestamp, row);
358
+ }
359
+ const rollingRows = [];
360
+ for (const timestamp of [...rowsByTimestamp.keys()].sort(
361
+ (left, right) => left - right
362
+ )) {
363
+ const expectedRows = [3, 2, 1, 0].map(
364
+ (offset) => rowsByTimestamp.get(timestamp - offset * quarterHourMs)
365
+ );
366
+ if (expectedRows.some((row) => row == null)) continue;
367
+ const completeRows = expectedRows;
368
+ const latest = completeRows[completeRows.length - 1];
369
+ rollingRows.push({
370
+ symbol: latest.symbol,
371
+ interval: "1h",
372
+ ts: new Date(timestamp),
373
+ openInterest: latest.openInterest ?? null,
374
+ fundingRate: latest.fundingRate ?? null,
375
+ liqLong: sumAvailable(completeRows.map((row) => row.liqLong)),
376
+ liqShort: sumAvailable(completeRows.map((row) => row.liqShort)),
377
+ liqTotal: sumAvailable(completeRows.map(getLiquidationTotal)),
378
+ source: `${latest.source ?? "coinalyze"}:rolling_15m`
379
+ });
380
+ }
381
+ return rollingRows;
382
+ };
383
+ var buildCoinalyzeHourlyRowsWithFallback = (params) => {
384
+ const hourMs = DERIVATIVES_INTERVAL_MS["1h"];
385
+ const rollingRows = deriveCoinalyzeRollingHourlyRowsFrom15m(params.rows15m);
386
+ const rollingHours = new Set(
387
+ rollingRows.map((row) => Math.floor(row.ts.getTime() / hourMs) * hourMs)
388
+ );
389
+ const fallbackRows = (params.fallbackRows1h ?? []).filter((row) => {
390
+ const timestamp = row.ts.getTime();
391
+ return row.interval === "1h" && Number.isFinite(timestamp) && timestamp % hourMs === 0 && !rollingHours.has(timestamp);
392
+ }).map((row) => ({
393
+ ...row,
394
+ source: `${row.source ?? "coinalyze"}:legacy_1h_fallback`
395
+ }));
396
+ return [...fallbackRows, ...rollingRows].sort(
397
+ (left, right) => left.ts.getTime() - right.ts.getTime()
398
+ );
399
+ };
271
400
 
272
401
  // src/utils/derivativesContext.ts
273
402
  var HOUR_MS = 60 * 60 * 1e3;
@@ -11925,11 +12054,13 @@ var createTrendlineEngine = (initialCandles, options) => {
11925
12054
  };
11926
12055
  // Annotate the CommonJS export names for ESM import in node:
11927
12056
  0 && (module.exports = {
12057
+ COINALYZE_MIN_INTRADAY_RETENTION_POINTS,
11928
12058
  COMPACT_INDICATORS_SNAPSHOT_KEY,
11929
12059
  COMPACT_INDICATORS_SNAPSHOT_SYMBOL,
11930
12060
  alignSortedCandlesByTimestamp,
11931
12061
  alignSpreadRows,
11932
12062
  applyIndicatorsToHistory,
12063
+ buildCoinalyzeHourlyRowsWithFallback,
11933
12064
  buildDerivativesContext,
11934
12065
  buildMlCandleIndicators,
11935
12066
  buildMlTimeframeIndicators,
@@ -11942,7 +12073,10 @@ var createTrendlineEngine = (initialCandles, options) => {
11942
12073
  createSerializableSpreadSmoother,
11943
12074
  createSpreadSmoother,
11944
12075
  createTrendlineEngine,
12076
+ deriveCoinalyzeHourlyRowsFrom15m,
12077
+ deriveCoinalyzeRollingHourlyRowsFrom15m,
11945
12078
  detectRawSupportResistance,
12079
+ getLastClosedDerivativesBarStartMs,
11946
12080
  getPluginIndicatorCatalog,
11947
12081
  getPluginIndicatorRenderers,
11948
12082
  getRegisteredIndicatorEntries,
@@ -11954,6 +12088,7 @@ var createTrendlineEngine = (initialCandles, options) => {
11954
12088
  normalizeDerivativesIntervals,
11955
12089
  registerIndicatorEntries,
11956
12090
  resetIndicatorRegistryCache,
12091
+ resolveCoinalyzeConfirmedIntradayCoverage,
11957
12092
  rollingMeanStd,
11958
12093
  smoothSpreadSeries,
11959
12094
  toArrayData,
@@ -1,9 +1,11 @@
1
1
  import {
2
+ COINALYZE_MIN_INTRADAY_RETENTION_POINTS,
2
3
  COMPACT_INDICATORS_SNAPSHOT_KEY,
3
4
  COMPACT_INDICATORS_SNAPSHOT_SYMBOL,
4
5
  alignSortedCandlesByTimestamp,
5
6
  alignSpreadRows,
6
7
  applyIndicatorsToHistory,
8
+ buildCoinalyzeHourlyRowsWithFallback,
7
9
  buildDerivativesContext,
8
10
  buildMlCandleIndicators,
9
11
  buildMlTimeframeIndicators,
@@ -16,7 +18,10 @@ import {
16
18
  createSerializableSpreadSmoother,
17
19
  createSpreadSmoother,
18
20
  createTrendlineEngine,
21
+ deriveCoinalyzeHourlyRowsFrom15m,
22
+ deriveCoinalyzeRollingHourlyRowsFrom15m,
19
23
  detectRawSupportResistance,
24
+ getLastClosedDerivativesBarStartMs,
20
25
  getPluginIndicatorCatalog,
21
26
  getPluginIndicatorRenderers,
22
27
  getRegisteredIndicatorEntries,
@@ -28,22 +33,25 @@ import {
28
33
  normalizeDerivativesIntervals,
29
34
  registerIndicatorEntries,
30
35
  resetIndicatorRegistryCache,
36
+ resolveCoinalyzeConfirmedIntradayCoverage,
31
37
  rollingMeanStd,
32
38
  smoothSpreadSeries,
33
39
  toArrayData,
34
40
  toCoinalyzeTimestampMs,
35
41
  toFiniteNumber
36
- } from "./chunk-EQEIRB6P.mjs";
42
+ } from "./chunk-HM7WDSPT.mjs";
37
43
  import "./chunk-AYC2QVKI.mjs";
38
44
  import "./chunk-M7QGVZ3J.mjs";
39
45
  import "./chunk-BOETNABM.mjs";
40
46
  import "./chunk-MKCQSB4H.mjs";
41
47
  export {
48
+ COINALYZE_MIN_INTRADAY_RETENTION_POINTS,
42
49
  COMPACT_INDICATORS_SNAPSHOT_KEY,
43
50
  COMPACT_INDICATORS_SNAPSHOT_SYMBOL,
44
51
  alignSortedCandlesByTimestamp,
45
52
  alignSpreadRows,
46
53
  applyIndicatorsToHistory,
54
+ buildCoinalyzeHourlyRowsWithFallback,
47
55
  buildDerivativesContext,
48
56
  buildMlCandleIndicators,
49
57
  buildMlTimeframeIndicators,
@@ -56,7 +64,10 @@ export {
56
64
  createSerializableSpreadSmoother,
57
65
  createSpreadSmoother,
58
66
  createTrendlineEngine,
67
+ deriveCoinalyzeHourlyRowsFrom15m,
68
+ deriveCoinalyzeRollingHourlyRowsFrom15m,
59
69
  detectRawSupportResistance,
70
+ getLastClosedDerivativesBarStartMs,
60
71
  getPluginIndicatorCatalog,
61
72
  getPluginIndicatorRenderers,
62
73
  getRegisteredIndicatorEntries,
@@ -68,6 +79,7 @@ export {
68
79
  normalizeDerivativesIntervals,
69
80
  registerIndicatorEntries,
70
81
  resetIndicatorRegistryCache,
82
+ resolveCoinalyzeConfirmedIntradayCoverage,
71
83
  rollingMeanStd,
72
84
  smoothSpreadSeries,
73
85
  toArrayData,
@@ -151,6 +151,12 @@ var calculateCoinBtcCorrelation = (coinCandles, btcCandles) => {
151
151
  };
152
152
  };
153
153
 
154
+ // src/utils/derivativesCoinalyze.ts
155
+ var DERIVATIVES_INTERVAL_MS = {
156
+ "15m": 15 * 60 * 1e3,
157
+ "1h": 60 * 60 * 1e3
158
+ };
159
+
154
160
  // src/utils/derivativesContext.ts
155
161
  var HOUR_MS = 60 * 60 * 1e3;
156
162
  var DEFAULT_STALE_AFTER_MS = {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createIndicators,
3
3
  getRequiredControllerSeedWindow
4
- } from "./chunk-EQEIRB6P.mjs";
4
+ } from "./chunk-HM7WDSPT.mjs";
5
5
  import "./chunk-AYC2QVKI.mjs";
6
6
  import "./chunk-M7QGVZ3J.mjs";
7
7
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tradejs/core",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "MIT-licensed browser-safe API for TradeJS config, strategy authoring, figures, and shared helpers.",
5
5
  "keywords": [
6
6
  "tradejs",
@@ -100,7 +100,7 @@
100
100
  }
101
101
  },
102
102
  "dependencies": {
103
- "@tradejs/types": "^2.0.0",
103
+ "@tradejs/types": "^2.0.2",
104
104
  "date-fns": "^3.3.1",
105
105
  "fast-technical-indicators": "^1.1.4",
106
106
  "klinecharts": "10.0.0-alpha9",