@tradejs/infra 1.0.6 → 1.0.9

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.js CHANGED
@@ -24,8 +24,10 @@ __export(timescale_exports, {
24
24
  findContinuityGap: () => findContinuityGap,
25
25
  getCandlesRange: () => getCandlesRange,
26
26
  getDataEdges: () => getDataEdges,
27
+ getDerivativesDataEdgesForSymbols: () => getDerivativesDataEdgesForSymbols,
27
28
  getDerivativesRangeForSymbols: () => getDerivativesRangeForSymbols,
28
29
  getDerivativesSummary: () => getDerivativesSummary,
30
+ getDerivativesWindow: () => getDerivativesWindow,
29
31
  getSpreadRangeForSymbols: () => getSpreadRangeForSymbols,
30
32
  getSpreadSummary: () => getSpreadSummary,
31
33
  toRows: () => toRows,
@@ -58,22 +60,33 @@ var getPool = () => {
58
60
  };
59
61
  var derivativesSchemaReady = false;
60
62
  var spreadSchemaReady = false;
61
- var toRows = (symbol, interval, data) => data.map((i) => ({
62
- symbol,
63
- interval,
64
- ts: new Date(i.timestamp),
65
- // ms -> Date
66
- open: i.open,
67
- high: i.high,
68
- low: i.low,
69
- close: i.close,
70
- volume: i.volume ?? null,
71
- turnover: i.turnover ?? null
72
- }));
63
+ var normalizeCandleProvider = (provider) => String(provider || "").trim().toLowerCase();
64
+ var normalizeCandleSymbol = (symbol) => String(symbol || "").trim().toUpperCase();
65
+ var toRows = (provider, symbol, interval, data) => {
66
+ const normalizedProvider = normalizeCandleProvider(provider);
67
+ if (!normalizedProvider) {
68
+ throw new Error("Candle provider is required");
69
+ }
70
+ const normalizedSymbol = normalizeCandleSymbol(symbol);
71
+ return data.map((i) => ({
72
+ provider: normalizedProvider,
73
+ symbol: normalizedSymbol,
74
+ interval,
75
+ ts: new Date(i.timestamp),
76
+ // ms -> Date
77
+ open: i.open,
78
+ high: i.high,
79
+ low: i.low,
80
+ close: i.close,
81
+ volume: i.volume ?? null,
82
+ turnover: i.turnover ?? null
83
+ }));
84
+ };
73
85
  async function upsertCandles(rows) {
74
86
  if (!rows.length) return;
75
87
  const pool = getPool();
76
88
  const cols = [
89
+ "provider",
77
90
  "symbol",
78
91
  "interval",
79
92
  "ts",
@@ -95,7 +108,8 @@ async function upsertCandles(rows) {
95
108
  (_, i) => `(${cols.map((__, j) => `$${i * cols.length + j + 1}`).join(",")})`
96
109
  ).join(",");
97
110
  const flat = rows.flatMap((r) => [
98
- r.symbol,
111
+ normalizeCandleProvider(r.provider),
112
+ normalizeCandleSymbol(r.symbol),
99
113
  r.interval,
100
114
  r.ts,
101
115
  r.open,
@@ -108,7 +122,7 @@ async function upsertCandles(rows) {
108
122
  const sql = `
109
123
  INSERT INTO candles (${cols.join(",")})
110
124
  VALUES ${valuesSql}
111
- ON CONFLICT (symbol, interval, ts) DO UPDATE SET
125
+ ON CONFLICT (provider, symbol, interval, ts) DO UPDATE SET
112
126
  open = EXCLUDED.open,
113
127
  high = EXCLUDED.high,
114
128
  low = EXCLUDED.low,
@@ -259,6 +273,82 @@ async function getDerivativesRangeForSymbols(symbols, interval, startMs, endMs)
259
273
  const res = await pool.query(sql, [symbols, interval, startMs, endMs]);
260
274
  return res.rows;
261
275
  }
276
+ async function getDerivativesDataEdgesForSymbols(symbols, interval) {
277
+ const normalizedSymbols = [
278
+ ...new Set(
279
+ symbols.map(
280
+ (symbol) => String(symbol || "").trim().toUpperCase()
281
+ ).filter(Boolean)
282
+ )
283
+ ];
284
+ const edges = /* @__PURE__ */ new Map();
285
+ if (!normalizedSymbols.length) return edges;
286
+ await ensureDerivativesSchema();
287
+ const pool = getPool();
288
+ const sql = `
289
+ SELECT
290
+ symbol,
291
+ extract(epoch from MIN(ts))*1000 AS min,
292
+ extract(epoch from MAX(ts))*1000 AS max
293
+ FROM derivatives_market
294
+ WHERE symbol = ANY($1)
295
+ AND interval = $2
296
+ GROUP BY symbol
297
+ `;
298
+ const res = await pool.query(sql, [normalizedSymbols, interval]);
299
+ for (const row of res.rows) {
300
+ const min = Number(row.min);
301
+ const max = Number(row.max);
302
+ edges.set(String(row.symbol).toUpperCase(), {
303
+ min: Number.isFinite(min) ? min : void 0,
304
+ max: Number.isFinite(max) ? max : void 0
305
+ });
306
+ }
307
+ return edges;
308
+ }
309
+ async function getDerivativesWindow(params) {
310
+ const { symbol, intervals, endMs, lookbackMs } = params;
311
+ const normalizedSymbol = String(symbol || "").trim().toUpperCase();
312
+ const normalizedIntervals = [...new Set(intervals)].filter(Boolean);
313
+ if (!normalizedSymbol || !normalizedIntervals.length) {
314
+ return {};
315
+ }
316
+ await ensureDerivativesSchema();
317
+ const startMs = endMs - Math.max(0, lookbackMs);
318
+ const pool = getPool();
319
+ const sql = `
320
+ SELECT symbol, interval, ts, open_interest, funding_rate, liq_long, liq_short, liq_total, source
321
+ FROM derivatives_market
322
+ WHERE symbol = $1
323
+ AND interval = ANY($2)
324
+ AND ts >= to_timestamp($3/1000.0)
325
+ AND ts <= to_timestamp($4/1000.0)
326
+ ORDER BY interval ASC, ts ASC
327
+ `;
328
+ const res = await pool.query(sql, [
329
+ normalizedSymbol,
330
+ normalizedIntervals,
331
+ startMs,
332
+ endMs
333
+ ]);
334
+ const rowsByInterval = {};
335
+ for (const row of res.rows) {
336
+ const interval = row.interval;
337
+ rowsByInterval[interval] ??= [];
338
+ rowsByInterval[interval]?.push({
339
+ symbol: row.symbol,
340
+ interval,
341
+ ts: row.ts,
342
+ openInterest: row.open_interest,
343
+ fundingRate: row.funding_rate,
344
+ liqLong: row.liq_long,
345
+ liqShort: row.liq_short,
346
+ liqTotal: row.liq_total,
347
+ source: row.source
348
+ });
349
+ }
350
+ return rowsByInterval;
351
+ }
262
352
  async function getDerivativesSummary(hours = 24, limit = 500) {
263
353
  await ensureDerivativesSchema();
264
354
  const pool = getPool();
@@ -398,39 +488,49 @@ async function getSpreadSummary(hours = 24, limit = 500) {
398
488
  hours: cappedHours
399
489
  };
400
490
  }
401
- async function getCandlesRange(symbol, interval, startMs, endMs) {
491
+ async function getCandlesRange(provider, symbol, interval, startMs, endMs) {
402
492
  const pool = getPool();
493
+ const normalizedProvider = normalizeCandleProvider(provider);
494
+ const normalizedSymbol = normalizeCandleSymbol(symbol);
403
495
  const sql = `
404
496
  SELECT symbol, interval, ts,
405
497
  open, high, low, close, volume, turnover
406
498
  FROM candles
407
- WHERE symbol = $1 AND interval = $2
408
- AND ts >= to_timestamp($3/1000.0)
409
- AND ts <= to_timestamp($4/1000.0)
499
+ WHERE provider = $1 AND symbol = $2 AND interval = $3
500
+ AND ts >= to_timestamp($4/1000.0)
501
+ AND ts <= to_timestamp($5/1000.0)
410
502
  ORDER BY ts ASC
411
503
  `;
412
- const res = await pool.query(sql, [symbol, interval, startMs, endMs]);
504
+ const res = await pool.query(sql, [
505
+ normalizedProvider,
506
+ normalizedSymbol,
507
+ interval,
508
+ startMs,
509
+ endMs
510
+ ]);
413
511
  return res.rows;
414
512
  }
415
- async function getDataEdges(symbol, interval) {
513
+ async function getDataEdges(provider, symbol, interval) {
416
514
  const pool = getPool();
515
+ const normalizedProvider = normalizeCandleProvider(provider);
516
+ const normalizedSymbol = normalizeCandleSymbol(symbol);
417
517
  const sqlMin = `
418
518
  SELECT extract(epoch from ts)*1000 AS ms
419
519
  FROM candles
420
- WHERE symbol=$1 AND interval=$2
520
+ WHERE provider=$1 AND symbol=$2 AND interval=$3
421
521
  ORDER BY ts ASC
422
522
  LIMIT 1
423
523
  `;
424
524
  const sqlMax = `
425
525
  SELECT extract(epoch from ts)*1000 AS ms
426
526
  FROM candles
427
- WHERE symbol=$1 AND interval=$2
527
+ WHERE provider=$1 AND symbol=$2 AND interval=$3
428
528
  ORDER BY ts DESC
429
529
  LIMIT 1
430
530
  `;
431
531
  const [minQ, maxQ] = await Promise.all([
432
- pool.query(sqlMin, [symbol, interval]),
433
- pool.query(sqlMax, [symbol, interval])
532
+ pool.query(sqlMin, [normalizedProvider, normalizedSymbol, interval]),
533
+ pool.query(sqlMax, [normalizedProvider, normalizedSymbol, interval])
434
534
  ]);
435
535
  const minRaw = minQ.rows[0]?.ms;
436
536
  const maxRaw = maxQ.rows[0]?.ms;
@@ -452,16 +552,20 @@ async function waitForDbReady(attempts = 20, delayMs = 1e3) {
452
552
  }
453
553
  throw lastError;
454
554
  }
455
- async function deleteCandles(symbol, interval) {
555
+ async function deleteCandles(provider, symbol, interval) {
456
556
  const pool = getPool();
557
+ const normalizedProvider = normalizeCandleProvider(provider);
558
+ const normalizedSymbol = normalizeCandleSymbol(symbol);
457
559
  const sql = `
458
560
  DELETE FROM candles
459
- WHERE symbol = $1 AND interval = $2
561
+ WHERE provider = $1 AND symbol = $2 AND interval = $3
460
562
  `;
461
- await pool.query(sql, [symbol, interval]);
563
+ await pool.query(sql, [normalizedProvider, normalizedSymbol, interval]);
462
564
  }
463
- async function findContinuityGap(symbol, interval) {
565
+ async function findContinuityGap(provider, symbol, interval) {
464
566
  const pool = getPool();
567
+ const normalizedProvider = normalizeCandleProvider(provider);
568
+ const normalizedSymbol = normalizeCandleSymbol(symbol);
465
569
  const expectedSeconds = interval * 60;
466
570
  const sql = `
467
571
  WITH ordered AS (
@@ -469,7 +573,7 @@ async function findContinuityGap(symbol, interval) {
469
573
  ts,
470
574
  LAG(ts) OVER (ORDER BY ts) AS prev_ts
471
575
  FROM candles
472
- WHERE symbol = $1 AND interval = $2
576
+ WHERE provider = $1 AND symbol = $2 AND interval = $3
473
577
  )
474
578
  SELECT
475
579
  ts,
@@ -477,11 +581,16 @@ async function findContinuityGap(symbol, interval) {
477
581
  EXTRACT(EPOCH FROM (ts - prev_ts))::int AS diff_seconds
478
582
  FROM ordered
479
583
  WHERE prev_ts IS NOT NULL
480
- AND EXTRACT(EPOCH FROM (ts - prev_ts))::int <> $3
584
+ AND EXTRACT(EPOCH FROM (ts - prev_ts))::int <> $4
481
585
  ORDER BY ts ASC
482
586
  LIMIT 1
483
587
  `;
484
- const res = await pool.query(sql, [symbol, interval, expectedSeconds]);
588
+ const res = await pool.query(sql, [
589
+ normalizedProvider,
590
+ normalizedSymbol,
591
+ interval,
592
+ expectedSeconds
593
+ ]);
485
594
  const row = res.rows[0];
486
595
  if (!row) return null;
487
596
  return {
@@ -496,8 +605,10 @@ async function findContinuityGap(symbol, interval) {
496
605
  findContinuityGap,
497
606
  getCandlesRange,
498
607
  getDataEdges,
608
+ getDerivativesDataEdgesForSymbols,
499
609
  getDerivativesRangeForSymbols,
500
610
  getDerivativesSummary,
611
+ getDerivativesWindow,
501
612
  getSpreadRangeForSymbols,
502
613
  getSpreadSummary,
503
614
  toRows,
@@ -22,22 +22,33 @@ var getPool = () => {
22
22
  };
23
23
  var derivativesSchemaReady = false;
24
24
  var spreadSchemaReady = false;
25
- var toRows = (symbol, interval, data) => data.map((i) => ({
26
- symbol,
27
- interval,
28
- ts: new Date(i.timestamp),
29
- // ms -> Date
30
- open: i.open,
31
- high: i.high,
32
- low: i.low,
33
- close: i.close,
34
- volume: i.volume ?? null,
35
- turnover: i.turnover ?? null
36
- }));
25
+ var normalizeCandleProvider = (provider) => String(provider || "").trim().toLowerCase();
26
+ var normalizeCandleSymbol = (symbol) => String(symbol || "").trim().toUpperCase();
27
+ var toRows = (provider, symbol, interval, data) => {
28
+ const normalizedProvider = normalizeCandleProvider(provider);
29
+ if (!normalizedProvider) {
30
+ throw new Error("Candle provider is required");
31
+ }
32
+ const normalizedSymbol = normalizeCandleSymbol(symbol);
33
+ return data.map((i) => ({
34
+ provider: normalizedProvider,
35
+ symbol: normalizedSymbol,
36
+ interval,
37
+ ts: new Date(i.timestamp),
38
+ // ms -> Date
39
+ open: i.open,
40
+ high: i.high,
41
+ low: i.low,
42
+ close: i.close,
43
+ volume: i.volume ?? null,
44
+ turnover: i.turnover ?? null
45
+ }));
46
+ };
37
47
  async function upsertCandles(rows) {
38
48
  if (!rows.length) return;
39
49
  const pool = getPool();
40
50
  const cols = [
51
+ "provider",
41
52
  "symbol",
42
53
  "interval",
43
54
  "ts",
@@ -59,7 +70,8 @@ async function upsertCandles(rows) {
59
70
  (_, i) => `(${cols.map((__, j) => `$${i * cols.length + j + 1}`).join(",")})`
60
71
  ).join(",");
61
72
  const flat = rows.flatMap((r) => [
62
- r.symbol,
73
+ normalizeCandleProvider(r.provider),
74
+ normalizeCandleSymbol(r.symbol),
63
75
  r.interval,
64
76
  r.ts,
65
77
  r.open,
@@ -72,7 +84,7 @@ async function upsertCandles(rows) {
72
84
  const sql = `
73
85
  INSERT INTO candles (${cols.join(",")})
74
86
  VALUES ${valuesSql}
75
- ON CONFLICT (symbol, interval, ts) DO UPDATE SET
87
+ ON CONFLICT (provider, symbol, interval, ts) DO UPDATE SET
76
88
  open = EXCLUDED.open,
77
89
  high = EXCLUDED.high,
78
90
  low = EXCLUDED.low,
@@ -223,6 +235,82 @@ async function getDerivativesRangeForSymbols(symbols, interval, startMs, endMs)
223
235
  const res = await pool.query(sql, [symbols, interval, startMs, endMs]);
224
236
  return res.rows;
225
237
  }
238
+ async function getDerivativesDataEdgesForSymbols(symbols, interval) {
239
+ const normalizedSymbols = [
240
+ ...new Set(
241
+ symbols.map(
242
+ (symbol) => String(symbol || "").trim().toUpperCase()
243
+ ).filter(Boolean)
244
+ )
245
+ ];
246
+ const edges = /* @__PURE__ */ new Map();
247
+ if (!normalizedSymbols.length) return edges;
248
+ await ensureDerivativesSchema();
249
+ const pool = getPool();
250
+ const sql = `
251
+ SELECT
252
+ symbol,
253
+ extract(epoch from MIN(ts))*1000 AS min,
254
+ extract(epoch from MAX(ts))*1000 AS max
255
+ FROM derivatives_market
256
+ WHERE symbol = ANY($1)
257
+ AND interval = $2
258
+ GROUP BY symbol
259
+ `;
260
+ const res = await pool.query(sql, [normalizedSymbols, interval]);
261
+ for (const row of res.rows) {
262
+ const min = Number(row.min);
263
+ const max = Number(row.max);
264
+ edges.set(String(row.symbol).toUpperCase(), {
265
+ min: Number.isFinite(min) ? min : void 0,
266
+ max: Number.isFinite(max) ? max : void 0
267
+ });
268
+ }
269
+ return edges;
270
+ }
271
+ async function getDerivativesWindow(params) {
272
+ const { symbol, intervals, endMs, lookbackMs } = params;
273
+ const normalizedSymbol = String(symbol || "").trim().toUpperCase();
274
+ const normalizedIntervals = [...new Set(intervals)].filter(Boolean);
275
+ if (!normalizedSymbol || !normalizedIntervals.length) {
276
+ return {};
277
+ }
278
+ await ensureDerivativesSchema();
279
+ const startMs = endMs - Math.max(0, lookbackMs);
280
+ const pool = getPool();
281
+ const sql = `
282
+ SELECT symbol, interval, ts, open_interest, funding_rate, liq_long, liq_short, liq_total, source
283
+ FROM derivatives_market
284
+ WHERE symbol = $1
285
+ AND interval = ANY($2)
286
+ AND ts >= to_timestamp($3/1000.0)
287
+ AND ts <= to_timestamp($4/1000.0)
288
+ ORDER BY interval ASC, ts ASC
289
+ `;
290
+ const res = await pool.query(sql, [
291
+ normalizedSymbol,
292
+ normalizedIntervals,
293
+ startMs,
294
+ endMs
295
+ ]);
296
+ const rowsByInterval = {};
297
+ for (const row of res.rows) {
298
+ const interval = row.interval;
299
+ rowsByInterval[interval] ??= [];
300
+ rowsByInterval[interval]?.push({
301
+ symbol: row.symbol,
302
+ interval,
303
+ ts: row.ts,
304
+ openInterest: row.open_interest,
305
+ fundingRate: row.funding_rate,
306
+ liqLong: row.liq_long,
307
+ liqShort: row.liq_short,
308
+ liqTotal: row.liq_total,
309
+ source: row.source
310
+ });
311
+ }
312
+ return rowsByInterval;
313
+ }
226
314
  async function getDerivativesSummary(hours = 24, limit = 500) {
227
315
  await ensureDerivativesSchema();
228
316
  const pool = getPool();
@@ -362,39 +450,49 @@ async function getSpreadSummary(hours = 24, limit = 500) {
362
450
  hours: cappedHours
363
451
  };
364
452
  }
365
- async function getCandlesRange(symbol, interval, startMs, endMs) {
453
+ async function getCandlesRange(provider, symbol, interval, startMs, endMs) {
366
454
  const pool = getPool();
455
+ const normalizedProvider = normalizeCandleProvider(provider);
456
+ const normalizedSymbol = normalizeCandleSymbol(symbol);
367
457
  const sql = `
368
458
  SELECT symbol, interval, ts,
369
459
  open, high, low, close, volume, turnover
370
460
  FROM candles
371
- WHERE symbol = $1 AND interval = $2
372
- AND ts >= to_timestamp($3/1000.0)
373
- AND ts <= to_timestamp($4/1000.0)
461
+ WHERE provider = $1 AND symbol = $2 AND interval = $3
462
+ AND ts >= to_timestamp($4/1000.0)
463
+ AND ts <= to_timestamp($5/1000.0)
374
464
  ORDER BY ts ASC
375
465
  `;
376
- const res = await pool.query(sql, [symbol, interval, startMs, endMs]);
466
+ const res = await pool.query(sql, [
467
+ normalizedProvider,
468
+ normalizedSymbol,
469
+ interval,
470
+ startMs,
471
+ endMs
472
+ ]);
377
473
  return res.rows;
378
474
  }
379
- async function getDataEdges(symbol, interval) {
475
+ async function getDataEdges(provider, symbol, interval) {
380
476
  const pool = getPool();
477
+ const normalizedProvider = normalizeCandleProvider(provider);
478
+ const normalizedSymbol = normalizeCandleSymbol(symbol);
381
479
  const sqlMin = `
382
480
  SELECT extract(epoch from ts)*1000 AS ms
383
481
  FROM candles
384
- WHERE symbol=$1 AND interval=$2
482
+ WHERE provider=$1 AND symbol=$2 AND interval=$3
385
483
  ORDER BY ts ASC
386
484
  LIMIT 1
387
485
  `;
388
486
  const sqlMax = `
389
487
  SELECT extract(epoch from ts)*1000 AS ms
390
488
  FROM candles
391
- WHERE symbol=$1 AND interval=$2
489
+ WHERE provider=$1 AND symbol=$2 AND interval=$3
392
490
  ORDER BY ts DESC
393
491
  LIMIT 1
394
492
  `;
395
493
  const [minQ, maxQ] = await Promise.all([
396
- pool.query(sqlMin, [symbol, interval]),
397
- pool.query(sqlMax, [symbol, interval])
494
+ pool.query(sqlMin, [normalizedProvider, normalizedSymbol, interval]),
495
+ pool.query(sqlMax, [normalizedProvider, normalizedSymbol, interval])
398
496
  ]);
399
497
  const minRaw = minQ.rows[0]?.ms;
400
498
  const maxRaw = maxQ.rows[0]?.ms;
@@ -416,16 +514,20 @@ async function waitForDbReady(attempts = 20, delayMs = 1e3) {
416
514
  }
417
515
  throw lastError;
418
516
  }
419
- async function deleteCandles(symbol, interval) {
517
+ async function deleteCandles(provider, symbol, interval) {
420
518
  const pool = getPool();
519
+ const normalizedProvider = normalizeCandleProvider(provider);
520
+ const normalizedSymbol = normalizeCandleSymbol(symbol);
421
521
  const sql = `
422
522
  DELETE FROM candles
423
- WHERE symbol = $1 AND interval = $2
523
+ WHERE provider = $1 AND symbol = $2 AND interval = $3
424
524
  `;
425
- await pool.query(sql, [symbol, interval]);
525
+ await pool.query(sql, [normalizedProvider, normalizedSymbol, interval]);
426
526
  }
427
- async function findContinuityGap(symbol, interval) {
527
+ async function findContinuityGap(provider, symbol, interval) {
428
528
  const pool = getPool();
529
+ const normalizedProvider = normalizeCandleProvider(provider);
530
+ const normalizedSymbol = normalizeCandleSymbol(symbol);
429
531
  const expectedSeconds = interval * 60;
430
532
  const sql = `
431
533
  WITH ordered AS (
@@ -433,7 +535,7 @@ async function findContinuityGap(symbol, interval) {
433
535
  ts,
434
536
  LAG(ts) OVER (ORDER BY ts) AS prev_ts
435
537
  FROM candles
436
- WHERE symbol = $1 AND interval = $2
538
+ WHERE provider = $1 AND symbol = $2 AND interval = $3
437
539
  )
438
540
  SELECT
439
541
  ts,
@@ -441,11 +543,16 @@ async function findContinuityGap(symbol, interval) {
441
543
  EXTRACT(EPOCH FROM (ts - prev_ts))::int AS diff_seconds
442
544
  FROM ordered
443
545
  WHERE prev_ts IS NOT NULL
444
- AND EXTRACT(EPOCH FROM (ts - prev_ts))::int <> $3
546
+ AND EXTRACT(EPOCH FROM (ts - prev_ts))::int <> $4
445
547
  ORDER BY ts ASC
446
548
  LIMIT 1
447
549
  `;
448
- const res = await pool.query(sql, [symbol, interval, expectedSeconds]);
550
+ const res = await pool.query(sql, [
551
+ normalizedProvider,
552
+ normalizedSymbol,
553
+ interval,
554
+ expectedSeconds
555
+ ]);
449
556
  const row = res.rows[0];
450
557
  if (!row) return null;
451
558
  return {
@@ -459,8 +566,10 @@ export {
459
566
  findContinuityGap,
460
567
  getCandlesRange,
461
568
  getDataEdges,
569
+ getDerivativesDataEdgesForSymbols,
462
570
  getDerivativesRangeForSymbols,
463
571
  getDerivativesSummary,
572
+ getDerivativesWindow,
464
573
  getSpreadRangeForSymbols,
465
574
  getSpreadSummary,
466
575
  toRows,
@@ -1,12 +1,13 @@
1
1
  interface UserRecord extends Record<string, unknown> {
2
2
  userName?: string;
3
3
  passwordHash?: string;
4
- token?: string;
5
4
  BYBIT_API_KEY?: string;
6
5
  BYBIT_API_SECRET?: string;
7
6
  COINALYZE_API_KEY?: string;
8
- OPENAI_API_KEY?: string;
9
- OPENAI_API_ENDPOINT?: string;
7
+ AI_API_KEY?: string;
8
+ AI_API_ENDPOINT?: string;
9
+ AI_MODEL?: string;
10
+ AI_RESPONSE_LANGUAGE?: string;
10
11
  TG_BOT_TOKEN?: string;
11
12
  TG_CHAT_ID?: string;
12
13
  updatedAt?: string;
@@ -15,10 +16,11 @@ interface UserSettings {
15
16
  userName: string;
16
17
  BYBIT_API_KEY: string;
17
18
  BYBIT_API_SECRET: string;
18
- token: string;
19
19
  COINALYZE_API_KEY: string;
20
- OPENAI_API_KEY: string;
21
- OPENAI_API_ENDPOINT: string;
20
+ AI_API_KEY: string;
21
+ AI_API_ENDPOINT: string;
22
+ AI_MODEL: string;
23
+ AI_RESPONSE_LANGUAGE: string;
22
24
  TG_BOT_TOKEN: string;
23
25
  TG_CHAT_ID: string;
24
26
  }
@@ -1,12 +1,13 @@
1
1
  interface UserRecord extends Record<string, unknown> {
2
2
  userName?: string;
3
3
  passwordHash?: string;
4
- token?: string;
5
4
  BYBIT_API_KEY?: string;
6
5
  BYBIT_API_SECRET?: string;
7
6
  COINALYZE_API_KEY?: string;
8
- OPENAI_API_KEY?: string;
9
- OPENAI_API_ENDPOINT?: string;
7
+ AI_API_KEY?: string;
8
+ AI_API_ENDPOINT?: string;
9
+ AI_MODEL?: string;
10
+ AI_RESPONSE_LANGUAGE?: string;
10
11
  TG_BOT_TOKEN?: string;
11
12
  TG_CHAT_ID?: string;
12
13
  updatedAt?: string;
@@ -15,10 +16,11 @@ interface UserSettings {
15
16
  userName: string;
16
17
  BYBIT_API_KEY: string;
17
18
  BYBIT_API_SECRET: string;
18
- token: string;
19
19
  COINALYZE_API_KEY: string;
20
- OPENAI_API_KEY: string;
21
- OPENAI_API_ENDPOINT: string;
20
+ AI_API_KEY: string;
21
+ AI_API_ENDPOINT: string;
22
+ AI_MODEL: string;
23
+ AI_RESPONSE_LANGUAGE: string;
22
24
  TG_BOT_TOKEN: string;
23
25
  TG_CHAT_ID: string;
24
26
  }