@tradejs/infra 2.0.18 → 2.0.20

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.
Files changed (62) hide show
  1. package/dist/ai.js +39 -74
  2. package/dist/ai.mjs +37 -74
  3. package/dist/chunk-2CZREG43.mjs +112 -0
  4. package/dist/chunk-DFMKDB2R.mjs +1285 -0
  5. package/dist/chunk-I2J6YDBD.mjs +910 -0
  6. package/dist/chunk-NWXFWTWU.mjs +1114 -0
  7. package/dist/chunk-SZQB7ER5.mjs +492 -0
  8. package/dist/chunk-YVIHTUV5.mjs +286 -0
  9. package/dist/coreResearch.d.mts +20 -0
  10. package/dist/coreResearch.d.ts +20 -0
  11. package/dist/coreResearch.js +89 -0
  12. package/dist/coreResearch.mjs +48 -0
  13. package/dist/internal-2coHaaos.d.mts +26 -0
  14. package/dist/internal-2coHaaos.d.ts +26 -0
  15. package/dist/ml.mjs +3 -3
  16. package/dist/runtimeDeployments.d.mts +10 -0
  17. package/dist/runtimeDeployments.d.ts +10 -0
  18. package/dist/runtimeDeployments.js +447 -0
  19. package/dist/runtimeDeployments.mjs +81 -0
  20. package/dist/runtimeStrategyConfigs.d.mts +28 -0
  21. package/dist/runtimeStrategyConfigs.d.ts +28 -0
  22. package/dist/runtimeStrategyConfigs.js +425 -0
  23. package/dist/runtimeStrategyConfigs.mjs +89 -0
  24. package/dist/strategyReleaseEvidence.d.mts +12 -0
  25. package/dist/strategyReleaseEvidence.d.ts +12 -0
  26. package/dist/strategyReleaseEvidence.js +120 -0
  27. package/dist/strategyReleaseEvidence.mjs +90 -0
  28. package/dist/timescale/candles.d.mts +38 -0
  29. package/dist/timescale/candles.d.ts +38 -0
  30. package/dist/timescale/candles.js +408 -0
  31. package/dist/timescale/candles.mjs +21 -0
  32. package/dist/timescale/client.d.mts +4 -0
  33. package/dist/timescale/client.d.ts +4 -0
  34. package/dist/timescale/client.js +109 -0
  35. package/dist/timescale/client.mjs +12 -0
  36. package/dist/timescale/derivatives.d.mts +90 -0
  37. package/dist/timescale/derivatives.d.ts +90 -0
  38. package/dist/timescale/derivatives.js +1270 -0
  39. package/dist/timescale/derivatives.mjs +26 -0
  40. package/dist/timescale/hyperliquidWhales.d.mts +149 -0
  41. package/dist/timescale/hyperliquidWhales.d.ts +149 -0
  42. package/dist/timescale/hyperliquidWhales.js +1893 -0
  43. package/dist/timescale/hyperliquidWhales.mjs +30 -0
  44. package/dist/timescale/marketContext.d.mts +188 -0
  45. package/dist/timescale/marketContext.d.ts +188 -0
  46. package/dist/timescale/marketContext.js +2091 -0
  47. package/dist/timescale/marketContext.mjs +60 -0
  48. package/dist/timescale/spread.d.mts +11 -0
  49. package/dist/timescale/spread.d.ts +11 -0
  50. package/dist/timescale/spread.js +215 -0
  51. package/dist/timescale/spread.mjs +11 -0
  52. package/dist/timescale.d.mts +9 -476
  53. package/dist/timescale.d.ts +9 -476
  54. package/dist/timescale.js +2121 -2112
  55. package/dist/timescale.mjs +73 -4070
  56. package/dist/tradingAccounts.d.mts +2 -8
  57. package/dist/tradingAccounts.d.ts +2 -8
  58. package/dist/tradingAccounts.js +0 -71
  59. package/dist/tradingAccounts.mjs +0 -65
  60. package/dist/values-BrvcmnfM.d.mts +6 -0
  61. package/dist/values-BrvcmnfM.d.ts +6 -0
  62. package/package.json +53 -2
package/dist/ai.js CHANGED
@@ -55,58 +55,7 @@ var import_promises2 = __toESM(require("fs/promises"));
55
55
  var import_path2 = __toESM(require("path"));
56
56
  var import_node_fs = require("fs");
57
57
  var import_node_readline2 = __toESM(require("readline"));
58
-
59
- // ../../node_modules/date-fns/toDate.mjs
60
- function toDate(argument) {
61
- const argStr = Object.prototype.toString.call(argument);
62
- if (argument instanceof Date || typeof argument === "object" && argStr === "[object Date]") {
63
- return new argument.constructor(+argument);
64
- } else if (typeof argument === "number" || argStr === "[object Number]" || typeof argument === "string" || argStr === "[object String]") {
65
- return new Date(argument);
66
- } else {
67
- return /* @__PURE__ */ new Date(NaN);
68
- }
69
- }
70
-
71
- // ../../node_modules/date-fns/constructFrom.mjs
72
- function constructFrom(date, value) {
73
- if (date instanceof Date) {
74
- return new date.constructor(value);
75
- } else {
76
- return new Date(value);
77
- }
78
- }
79
-
80
- // ../../node_modules/date-fns/addMonths.mjs
81
- function addMonths(date, amount) {
82
- const _date = toDate(date);
83
- if (isNaN(amount)) return constructFrom(date, NaN);
84
- if (!amount) {
85
- return _date;
86
- }
87
- const dayOfMonth = _date.getDate();
88
- const endOfDesiredMonth = constructFrom(date, _date.getTime());
89
- endOfDesiredMonth.setMonth(_date.getMonth() + amount + 1, 0);
90
- const daysInMonth = endOfDesiredMonth.getDate();
91
- if (dayOfMonth >= daysInMonth) {
92
- return endOfDesiredMonth;
93
- } else {
94
- _date.setFullYear(
95
- endOfDesiredMonth.getFullYear(),
96
- endOfDesiredMonth.getMonth(),
97
- dayOfMonth
98
- );
99
- return _date;
100
- }
101
- }
102
-
103
- // ../../node_modules/date-fns/startOfMonth.mjs
104
- function startOfMonth(date) {
105
- const _date = toDate(date);
106
- _date.setDate(1);
107
- _date.setHours(0, 0, 0, 0);
108
- return _date;
109
- }
58
+ var import_date_fns = require("date-fns");
110
59
 
111
60
  // src/mlDatasetFile.ts
112
61
  var import_events = require("events");
@@ -185,21 +134,32 @@ var getRunIdFromAiChunkFileName = (strategyName, fileName) => {
185
134
  var appendAiDatasetRow = async (params) => {
186
135
  const { strategyName, chunkId, row, outDir = DEFAULT_DIR } = params;
187
136
  const filePath = getAiChunkFilePath(strategyName, chunkId, outDir);
188
- let state = writerByPath.get(filePath);
189
- if (!state) {
190
- await import_promises2.default.mkdir(outDir, { recursive: true });
191
- const stream = (0, import_fs2.createWriteStream)(filePath, {
192
- encoding: "utf8",
193
- flags: "a"
194
- });
195
- state = {
196
- filePath,
197
- stream,
198
- buffer: [],
199
- writeQueue: Promise.resolve(),
200
- closed: false
201
- };
202
- writerByPath.set(filePath, state);
137
+ let statePromise = writerByPath.get(filePath);
138
+ if (!statePromise) {
139
+ statePromise = (async () => {
140
+ await import_promises2.default.mkdir(outDir, { recursive: true });
141
+ const stream = (0, import_fs2.createWriteStream)(filePath, {
142
+ encoding: "utf8",
143
+ flags: "a"
144
+ });
145
+ return {
146
+ filePath,
147
+ stream,
148
+ buffer: [],
149
+ writeQueue: Promise.resolve(),
150
+ closed: false
151
+ };
152
+ })();
153
+ writerByPath.set(filePath, statePromise);
154
+ }
155
+ let state;
156
+ try {
157
+ state = await statePromise;
158
+ } catch (error) {
159
+ if (writerByPath.get(filePath) === statePromise) {
160
+ writerByPath.delete(filePath);
161
+ }
162
+ throw error;
203
163
  }
204
164
  if (state.closed) {
205
165
  throw new Error(`AI dataset writer is closed: ${filePath}`);
@@ -222,10 +182,12 @@ var flushState = async (state) => {
222
182
  }
223
183
  };
224
184
  var flushAiDatasetWriter = async (filePath) => {
225
- const state = writerByPath.get(filePath);
226
- if (!state || state.closed) {
185
+ const statePromise = writerByPath.get(filePath);
186
+ if (!statePromise) {
227
187
  return;
228
188
  }
189
+ const state = await statePromise;
190
+ if (state.closed) return;
229
191
  state.writeQueue = state.writeQueue.then(() => flushState(state));
230
192
  await state.writeQueue;
231
193
  };
@@ -242,13 +204,16 @@ var closeState = async (state) => {
242
204
  ]);
243
205
  };
244
206
  var closeAiDatasetWriter = async (filePath) => {
245
- const state = writerByPath.get(filePath);
246
- if (!state) {
207
+ const statePromise = writerByPath.get(filePath);
208
+ if (!statePromise) {
247
209
  return;
248
210
  }
211
+ const state = await statePromise;
249
212
  state.writeQueue = state.writeQueue.then(() => closeState(state));
250
213
  await state.writeQueue;
251
- writerByPath.delete(filePath);
214
+ if (writerByPath.get(filePath) === statePromise) {
215
+ writerByPath.delete(filePath);
216
+ }
252
217
  };
253
218
  var closeAllAiDatasetWriters = async () => {
254
219
  const filePaths = [...writerByPath.keys()];
@@ -570,8 +535,8 @@ var getAiDatasetPartPath = (filePath, partIndex) => {
570
535
  return import_path2.default.join(parsed.dir, `${parsed.name}-part${partIndex}${parsed.ext}`);
571
536
  };
572
537
  var getPartWindowEndExclusive = (timestamp, monthsPerPart) => {
573
- const partStart = startOfMonth(new Date(timestamp));
574
- return addMonths(partStart, Math.max(1, monthsPerPart)).getTime();
538
+ const partStart = (0, import_date_fns.startOfMonth)(new Date(timestamp));
539
+ return (0, import_date_fns.addMonths)(partStart, Math.max(1, monthsPerPart)).getTime();
575
540
  };
576
541
  var splitAiMergedDatasetFile = async (params) => {
577
542
  const { filePath, monthsPerPart = 2 } = params;
package/dist/ai.mjs CHANGED
@@ -10,60 +10,7 @@ import fs from "fs/promises";
10
10
  import path from "path";
11
11
  import { createReadStream } from "fs";
12
12
  import readline from "readline";
13
-
14
- // ../../node_modules/date-fns/toDate.mjs
15
- function toDate(argument) {
16
- const argStr = Object.prototype.toString.call(argument);
17
- if (argument instanceof Date || typeof argument === "object" && argStr === "[object Date]") {
18
- return new argument.constructor(+argument);
19
- } else if (typeof argument === "number" || argStr === "[object Number]" || typeof argument === "string" || argStr === "[object String]") {
20
- return new Date(argument);
21
- } else {
22
- return /* @__PURE__ */ new Date(NaN);
23
- }
24
- }
25
-
26
- // ../../node_modules/date-fns/constructFrom.mjs
27
- function constructFrom(date, value) {
28
- if (date instanceof Date) {
29
- return new date.constructor(value);
30
- } else {
31
- return new Date(value);
32
- }
33
- }
34
-
35
- // ../../node_modules/date-fns/addMonths.mjs
36
- function addMonths(date, amount) {
37
- const _date = toDate(date);
38
- if (isNaN(amount)) return constructFrom(date, NaN);
39
- if (!amount) {
40
- return _date;
41
- }
42
- const dayOfMonth = _date.getDate();
43
- const endOfDesiredMonth = constructFrom(date, _date.getTime());
44
- endOfDesiredMonth.setMonth(_date.getMonth() + amount + 1, 0);
45
- const daysInMonth = endOfDesiredMonth.getDate();
46
- if (dayOfMonth >= daysInMonth) {
47
- return endOfDesiredMonth;
48
- } else {
49
- _date.setFullYear(
50
- endOfDesiredMonth.getFullYear(),
51
- endOfDesiredMonth.getMonth(),
52
- dayOfMonth
53
- );
54
- return _date;
55
- }
56
- }
57
-
58
- // ../../node_modules/date-fns/startOfMonth.mjs
59
- function startOfMonth(date) {
60
- const _date = toDate(date);
61
- _date.setDate(1);
62
- _date.setHours(0, 0, 0, 0);
63
- return _date;
64
- }
65
-
66
- // src/aiDatasetFile.ts
13
+ import { addMonths, startOfMonth } from "date-fns";
67
14
  var DEFAULT_DIR = "data/ai/export";
68
15
  var AI_DATASET_WRITE_BATCH_SIZE = 100;
69
16
  var AI_MERGE_SORT_RUN_MAX_ROWS = 2e3;
@@ -88,21 +35,32 @@ var getRunIdFromAiChunkFileName = (strategyName, fileName) => {
88
35
  var appendAiDatasetRow = async (params) => {
89
36
  const { strategyName, chunkId, row, outDir = DEFAULT_DIR } = params;
90
37
  const filePath = getAiChunkFilePath(strategyName, chunkId, outDir);
91
- let state = writerByPath.get(filePath);
92
- if (!state) {
93
- await fs.mkdir(outDir, { recursive: true });
94
- const stream = createWriteStream(filePath, {
95
- encoding: "utf8",
96
- flags: "a"
97
- });
98
- state = {
99
- filePath,
100
- stream,
101
- buffer: [],
102
- writeQueue: Promise.resolve(),
103
- closed: false
104
- };
105
- writerByPath.set(filePath, state);
38
+ let statePromise = writerByPath.get(filePath);
39
+ if (!statePromise) {
40
+ statePromise = (async () => {
41
+ await fs.mkdir(outDir, { recursive: true });
42
+ const stream = createWriteStream(filePath, {
43
+ encoding: "utf8",
44
+ flags: "a"
45
+ });
46
+ return {
47
+ filePath,
48
+ stream,
49
+ buffer: [],
50
+ writeQueue: Promise.resolve(),
51
+ closed: false
52
+ };
53
+ })();
54
+ writerByPath.set(filePath, statePromise);
55
+ }
56
+ let state;
57
+ try {
58
+ state = await statePromise;
59
+ } catch (error) {
60
+ if (writerByPath.get(filePath) === statePromise) {
61
+ writerByPath.delete(filePath);
62
+ }
63
+ throw error;
106
64
  }
107
65
  if (state.closed) {
108
66
  throw new Error(`AI dataset writer is closed: ${filePath}`);
@@ -125,10 +83,12 @@ var flushState = async (state) => {
125
83
  }
126
84
  };
127
85
  var flushAiDatasetWriter = async (filePath) => {
128
- const state = writerByPath.get(filePath);
129
- if (!state || state.closed) {
86
+ const statePromise = writerByPath.get(filePath);
87
+ if (!statePromise) {
130
88
  return;
131
89
  }
90
+ const state = await statePromise;
91
+ if (state.closed) return;
132
92
  state.writeQueue = state.writeQueue.then(() => flushState(state));
133
93
  await state.writeQueue;
134
94
  };
@@ -145,13 +105,16 @@ var closeState = async (state) => {
145
105
  ]);
146
106
  };
147
107
  var closeAiDatasetWriter = async (filePath) => {
148
- const state = writerByPath.get(filePath);
149
- if (!state) {
108
+ const statePromise = writerByPath.get(filePath);
109
+ if (!statePromise) {
150
110
  return;
151
111
  }
112
+ const state = await statePromise;
152
113
  state.writeQueue = state.writeQueue.then(() => closeState(state));
153
114
  await state.writeQueue;
154
- writerByPath.delete(filePath);
115
+ if (writerByPath.get(filePath) === statePromise) {
116
+ writerByPath.delete(filePath);
117
+ }
155
118
  };
156
119
  var closeAllAiDatasetWriters = async () => {
157
120
  const filePaths = [...writerByPath.keys()];
@@ -0,0 +1,112 @@
1
+ import {
2
+ ensureSpreadSchema,
3
+ getPool
4
+ } from "./chunk-I2J6YDBD.mjs";
5
+
6
+ // src/timescale/spread.ts
7
+ async function upsertSpreadRows(rows) {
8
+ if (!rows.length) return;
9
+ await ensureSpreadSchema();
10
+ const pool = getPool();
11
+ const cols = [
12
+ "symbol",
13
+ "interval",
14
+ "ts",
15
+ "binance_price",
16
+ "coinbase_price",
17
+ "spread",
18
+ "source"
19
+ ];
20
+ const maxRows = Math.floor(65535 / cols.length);
21
+ if (rows.length > maxRows) {
22
+ for (let i = 0; i < rows.length; i += maxRows) {
23
+ await upsertSpreadRows(rows.slice(i, i + maxRows));
24
+ }
25
+ return;
26
+ }
27
+ const valuesSql = rows.map(
28
+ (_, i) => `(${cols.map((__, j) => `$${i * cols.length + j + 1}`).join(",")})`
29
+ ).join(",");
30
+ const flat = rows.flatMap((row) => [
31
+ row.symbol,
32
+ row.interval,
33
+ row.ts,
34
+ row.binancePrice ?? null,
35
+ row.coinbasePrice ?? null,
36
+ row.spread ?? null,
37
+ row.source ?? null
38
+ ]);
39
+ const sql = `
40
+ INSERT INTO market_spread (${cols.join(",")})
41
+ VALUES ${valuesSql}
42
+ ON CONFLICT (symbol, interval, ts) DO UPDATE SET
43
+ binance_price = COALESCE(EXCLUDED.binance_price, market_spread.binance_price),
44
+ coinbase_price = COALESCE(EXCLUDED.coinbase_price, market_spread.coinbase_price),
45
+ spread = COALESCE(EXCLUDED.spread, market_spread.spread),
46
+ source = COALESCE(EXCLUDED.source, market_spread.source),
47
+ ingested_at = now()
48
+ `;
49
+ await pool.query(sql, flat);
50
+ }
51
+ async function getSpreadRangeForSymbols(symbols, interval, startMs, endMs) {
52
+ if (!symbols.length) {
53
+ return [];
54
+ }
55
+ await ensureSpreadSchema();
56
+ const pool = getPool();
57
+ const sql = `
58
+ SELECT symbol, interval, ts, binance_price, coinbase_price, spread
59
+ FROM market_spread
60
+ WHERE symbol = ANY($1)
61
+ AND interval = $2
62
+ AND ts >= to_timestamp($3/1000.0)
63
+ AND ts <= to_timestamp($4/1000.0)
64
+ ORDER BY symbol ASC, ts ASC
65
+ `;
66
+ const res = await pool.query(sql, [symbols, interval, startMs, endMs]);
67
+ return res.rows;
68
+ }
69
+ async function getSpreadSummary(hours = 24, limit = 500) {
70
+ await ensureSpreadSchema();
71
+ const pool = getPool();
72
+ const cappedHours = Math.max(1, Math.min(24 * 30, hours));
73
+ const cappedLimit = Math.max(50, Math.min(5e3, limit));
74
+ const rowsQ = await pool.query(
75
+ `
76
+ SELECT symbol, interval, ts, binance_price, coinbase_price, spread
77
+ FROM market_spread
78
+ WHERE ts >= now() - ($1 || ' hours')::interval
79
+ ORDER BY ts DESC
80
+ LIMIT $2
81
+ `,
82
+ [String(cappedHours), cappedLimit]
83
+ );
84
+ const aggQ = await pool.query(
85
+ `
86
+ SELECT
87
+ symbol,
88
+ interval,
89
+ COUNT(*)::int AS points,
90
+ MAX(ts) AS last_ts,
91
+ AVG(spread) AS avg_spread,
92
+ STDDEV_POP(spread) AS std_spread
93
+ FROM market_spread
94
+ WHERE ts >= now() - ($1 || ' hours')::interval
95
+ GROUP BY symbol, interval
96
+ ORDER BY points DESC, symbol ASC
97
+ LIMIT 500
98
+ `,
99
+ [String(cappedHours)]
100
+ );
101
+ return {
102
+ rows: rowsQ.rows,
103
+ aggregates: aggQ.rows,
104
+ hours: cappedHours
105
+ };
106
+ }
107
+
108
+ export {
109
+ upsertSpreadRows,
110
+ getSpreadRangeForSymbols,
111
+ getSpreadSummary
112
+ };