@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/aiEndpoints.d.mts +10 -0
- package/dist/aiEndpoints.d.ts +10 -0
- package/dist/aiEndpoints.js +159 -0
- package/dist/aiEndpoints.mjs +12 -0
- package/dist/aiLanguages.d.mts +11 -0
- package/dist/aiLanguages.d.ts +11 -0
- package/dist/aiLanguages.js +71 -0
- package/dist/aiLanguages.mjs +12 -0
- package/dist/aiModels.d.mts +12 -0
- package/dist/aiModels.d.ts +12 -0
- package/dist/aiModels.js +272 -0
- package/dist/aiModels.mjs +17 -0
- package/dist/chunk-CCC7DX2T.mjs +44 -0
- package/dist/chunk-DTCLZIBM.mjs +163 -0
- package/dist/{chunk-EFARW5QE.mjs → chunk-MLVWC2I2.mjs} +173 -0
- package/dist/chunk-XQ3YBULV.mjs +132 -0
- package/dist/ml.js +119 -0
- package/dist/ml.mjs +119 -0
- package/dist/redis.d.mts +27 -1
- package/dist/redis.d.ts +27 -1
- package/dist/redis.js +181 -2
- package/dist/redis.mjs +15 -3
- package/dist/timescale.d.mts +18 -7
- package/dist/timescale.d.ts +18 -7
- package/dist/timescale.js +142 -31
- package/dist/timescale.mjs +140 -31
- package/dist/userSettings.d.mts +8 -6
- package/dist/userSettings.d.ts +8 -6
- package/dist/userSettings.js +342 -4
- package/dist/userSettings.mjs +27 -5
- package/package.json +18 -3
package/dist/ml.mjs
CHANGED
|
@@ -425,6 +425,44 @@ var INDICATOR_TIMEFRAMES = [
|
|
|
425
425
|
{ label: "TF4H", suffix: "4h" },
|
|
426
426
|
{ label: "TF1D", suffix: "1d" }
|
|
427
427
|
];
|
|
428
|
+
var DERIVATIVES_INTERVALS = [
|
|
429
|
+
{ label: "15M", key: "15m" },
|
|
430
|
+
{ label: "1H", key: "1h" }
|
|
431
|
+
];
|
|
432
|
+
var DERIVATIVES_PRESSURES = [
|
|
433
|
+
"neutral",
|
|
434
|
+
"crowded_long",
|
|
435
|
+
"crowded_short",
|
|
436
|
+
"long_flush",
|
|
437
|
+
"short_flush"
|
|
438
|
+
];
|
|
439
|
+
var DERIVATIVES_PRESSURE_LABELS = {
|
|
440
|
+
neutral: "Neutral",
|
|
441
|
+
crowded_long: "CrowdedLong",
|
|
442
|
+
crowded_short: "CrowdedShort",
|
|
443
|
+
long_flush: "LongFlush",
|
|
444
|
+
short_flush: "ShortFlush"
|
|
445
|
+
};
|
|
446
|
+
var DERIVATIVES_RISK_FLAGS = [
|
|
447
|
+
"missing_derivatives",
|
|
448
|
+
"stale_derivatives",
|
|
449
|
+
"crowded_long",
|
|
450
|
+
"crowded_short",
|
|
451
|
+
"oi_falling",
|
|
452
|
+
"oi_not_confirming",
|
|
453
|
+
"long_liquidation_spike",
|
|
454
|
+
"short_liquidation_spike"
|
|
455
|
+
];
|
|
456
|
+
var DERIVATIVES_RISK_FLAG_LABELS = {
|
|
457
|
+
missing_derivatives: "Missing",
|
|
458
|
+
stale_derivatives: "Stale",
|
|
459
|
+
crowded_long: "CrowdedLong",
|
|
460
|
+
crowded_short: "CrowdedShort",
|
|
461
|
+
oi_falling: "OiFalling",
|
|
462
|
+
oi_not_confirming: "OiNotConfirming",
|
|
463
|
+
long_liquidation_spike: "LongLiqSpike",
|
|
464
|
+
short_liquidation_spike: "ShortLiqSpike"
|
|
465
|
+
};
|
|
428
466
|
var toNumber = (value, fallback = 0) => {
|
|
429
467
|
if (typeof value === "number") {
|
|
430
468
|
return Number.isFinite(value) ? value : fallback;
|
|
@@ -545,6 +583,7 @@ var sliceWindow = (values, endIndex, windowSize) => {
|
|
|
545
583
|
return values.slice(start, endIndex + 1);
|
|
546
584
|
};
|
|
547
585
|
var asArray = (value) => Array.isArray(value) ? value : [];
|
|
586
|
+
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
548
587
|
var dropLastFromIndicatorSeries = (indicators) => {
|
|
549
588
|
if (!ML_WINDOW_POLICY.dropLastIndicatorElement) {
|
|
550
589
|
return indicators;
|
|
@@ -1266,6 +1305,85 @@ var buildMlTrainingRow = (signalRecord, resultRecord) => {
|
|
|
1266
1305
|
row.TrendLine_Slope = null;
|
|
1267
1306
|
}
|
|
1268
1307
|
};
|
|
1308
|
+
const applyDerivativesPhase = () => {
|
|
1309
|
+
const context2 = asRecord(signal?.additionalIndicators?.derivativesContext);
|
|
1310
|
+
const summary = asRecord(context2?.summary);
|
|
1311
|
+
const intervals = asRecord(context2?.intervals);
|
|
1312
|
+
const pressure = typeof summary?.pressure === "string" ? summary.pressure : "";
|
|
1313
|
+
const riskFlags = new Set(
|
|
1314
|
+
asArray(summary?.riskFlags).map((flag) => String(flag))
|
|
1315
|
+
);
|
|
1316
|
+
row.Deriv_HasContext = context2 ? 1 : 0;
|
|
1317
|
+
row.Deriv_Source_Coinalyze = context2?.source === "coinalyze" ? 1 : 0;
|
|
1318
|
+
row.Deriv_DirectionAligned = summary?.directionAligned === true ? 1 : summary?.directionAligned === false ? -1 : 0;
|
|
1319
|
+
for (const pressureName of DERIVATIVES_PRESSURES) {
|
|
1320
|
+
row[`Deriv_Pressure_${DERIVATIVES_PRESSURE_LABELS[pressureName]}`] = pressure === pressureName ? 1 : 0;
|
|
1321
|
+
}
|
|
1322
|
+
for (const riskFlag of DERIVATIVES_RISK_FLAGS) {
|
|
1323
|
+
row[`Deriv_Flag_${DERIVATIVES_RISK_FLAG_LABELS[riskFlag]}`] = riskFlags.has(riskFlag) ? 1 : 0;
|
|
1324
|
+
}
|
|
1325
|
+
for (const { label, key: intervalKey } of DERIVATIVES_INTERVALS) {
|
|
1326
|
+
const intervalContext = asRecord(intervals?.[intervalKey]);
|
|
1327
|
+
const prefix = `Deriv_${label}`;
|
|
1328
|
+
const asOfTs = toNumber(intervalContext?.asOfTs, entryTimestamp);
|
|
1329
|
+
const ageHours = intervalContext ? Math.max(0, safeDiv2(entryTimestamp - asOfTs, 60 * 60 * 1e3)) : 0;
|
|
1330
|
+
row[`${prefix}_Present`] = intervalContext ? 1 : 0;
|
|
1331
|
+
row[`${prefix}_Stale`] = intervalContext?.stale === true ? 1 : 0;
|
|
1332
|
+
row[`${prefix}_AgeHours_Log`] = safeLog1pPositive(ageHours);
|
|
1333
|
+
row[`${prefix}_Points_Log`] = safeLog1pPositive(
|
|
1334
|
+
toNumber(intervalContext?.points, 0)
|
|
1335
|
+
);
|
|
1336
|
+
row[`${prefix}_OpenInterest_Log`] = safeLog1pPositive(
|
|
1337
|
+
toNumber(intervalContext?.openInterest, 0)
|
|
1338
|
+
);
|
|
1339
|
+
row[`${prefix}_OiChange1h`] = clamp2(
|
|
1340
|
+
toNumber(intervalContext?.oiChangePct1h, 0) / 100,
|
|
1341
|
+
-5,
|
|
1342
|
+
5
|
|
1343
|
+
);
|
|
1344
|
+
row[`${prefix}_OiChange4h`] = clamp2(
|
|
1345
|
+
toNumber(intervalContext?.oiChangePct4h, 0) / 100,
|
|
1346
|
+
-5,
|
|
1347
|
+
5
|
|
1348
|
+
);
|
|
1349
|
+
row[`${prefix}_OiChange24h`] = clamp2(
|
|
1350
|
+
toNumber(intervalContext?.oiChangePct24h, 0) / 100,
|
|
1351
|
+
-5,
|
|
1352
|
+
5
|
|
1353
|
+
);
|
|
1354
|
+
row[`${prefix}_FundingBps`] = clamp2(
|
|
1355
|
+
toNumber(intervalContext?.fundingRate, 0) * 1e4,
|
|
1356
|
+
-100,
|
|
1357
|
+
100
|
|
1358
|
+
);
|
|
1359
|
+
row[`${prefix}_FundingZ`] = clamp2(
|
|
1360
|
+
toNumber(intervalContext?.fundingZScore, 0),
|
|
1361
|
+
-8,
|
|
1362
|
+
8
|
|
1363
|
+
);
|
|
1364
|
+
row[`${prefix}_LiqLong_Log`] = safeLog1pPositive(
|
|
1365
|
+
toNumber(intervalContext?.liqLong, 0)
|
|
1366
|
+
);
|
|
1367
|
+
row[`${prefix}_LiqShort_Log`] = safeLog1pPositive(
|
|
1368
|
+
toNumber(intervalContext?.liqShort, 0)
|
|
1369
|
+
);
|
|
1370
|
+
row[`${prefix}_LiqTotal_Log`] = safeLog1pPositive(
|
|
1371
|
+
toNumber(intervalContext?.liqTotal, 0)
|
|
1372
|
+
);
|
|
1373
|
+
row[`${prefix}_LiqImbalance`] = clamp2(
|
|
1374
|
+
toNumber(intervalContext?.liqImbalance, 0),
|
|
1375
|
+
-1,
|
|
1376
|
+
1
|
|
1377
|
+
);
|
|
1378
|
+
row[`${prefix}_LiqSpike_Log`] = safeLog1pPositive(
|
|
1379
|
+
toNumber(intervalContext?.liqSpikeRatio, 0)
|
|
1380
|
+
);
|
|
1381
|
+
row[`${prefix}_LiqSpike_Squashed`] = squash(
|
|
1382
|
+
toNumber(intervalContext?.liqSpikeRatio, 0),
|
|
1383
|
+
3
|
|
1384
|
+
);
|
|
1385
|
+
}
|
|
1386
|
+
};
|
|
1269
1387
|
const applyLabelPhase = () => {
|
|
1270
1388
|
const profit = toNumber(resultRecord?.profit, NaN);
|
|
1271
1389
|
row.label = Number.isFinite(profit) ? profit > 0 ? 1 : 0 : null;
|
|
@@ -1275,6 +1393,7 @@ var buildMlTrainingRow = (signalRecord, resultRecord) => {
|
|
|
1275
1393
|
applyRegimePhase();
|
|
1276
1394
|
applySeriesAnalysisPhase();
|
|
1277
1395
|
applyTrendlinePhase();
|
|
1396
|
+
applyDerivativesPhase();
|
|
1278
1397
|
applyLabelPhase();
|
|
1279
1398
|
return row;
|
|
1280
1399
|
};
|
package/dist/redis.d.mts
CHANGED
|
@@ -17,6 +17,12 @@ declare class RedisWriteBlockedError extends Error {
|
|
|
17
17
|
}
|
|
18
18
|
declare const delKeyWithOptions: (key: string, options?: DelKeyOptions) => Promise<boolean>;
|
|
19
19
|
declare const setData: <T>(key: string, data: T, options?: Options) => Promise<void>;
|
|
20
|
+
declare const setHashJsonField: <T>(key: string, field: string, data: T, options?: Options) => Promise<void>;
|
|
21
|
+
declare const getHashJsonValues: <T>(key: string) => Promise<T[]>;
|
|
22
|
+
declare const incrHashFields: (key: string, increments: Record<string, number>, options?: Options) => Promise<void>;
|
|
23
|
+
declare const getHashData: (key: string) => Promise<Record<string, string>>;
|
|
24
|
+
declare const createScreenshotSessionToken: (userName: string) => Promise<string | null>;
|
|
25
|
+
declare const consumeScreenshotSessionToken: (token: string) => Promise<string | null>;
|
|
20
26
|
declare const redisKeys: {
|
|
21
27
|
users: () => string;
|
|
22
28
|
user: (userName: string) => string;
|
|
@@ -31,14 +37,34 @@ declare const redisKeys: {
|
|
|
31
37
|
testOrders: (userName: string, strategyName: string, testName: string) => string;
|
|
32
38
|
testConfig: (userName: string, strategyName: string, testName: string) => string;
|
|
33
39
|
testStat: (userName: string, strategyName: string, testName: string) => string;
|
|
40
|
+
testSummaries: (userName: string) => string;
|
|
34
41
|
cacheChunk: (userName: string, chunkId: string) => string;
|
|
35
42
|
cacheOrders: (userName: string, orderLogId: string) => string;
|
|
36
43
|
cachePositions: (userName: string, orderLogId: string) => string;
|
|
37
44
|
signal: (symbol: string, signalId: string) => string;
|
|
38
45
|
signalsBySymbol: (symbol: string) => string;
|
|
39
46
|
storeSignal: (symbol: string, signalId: string) => string;
|
|
47
|
+
runtimeSignals: (userName: string) => string;
|
|
48
|
+
runtimeSignal: (userName: string, signalId: string) => string;
|
|
49
|
+
runtimeSignalBuckets: (userName: string) => string;
|
|
50
|
+
runtimeSignalBucket: (userName: string, dayKey: string, strategyName: string) => string;
|
|
51
|
+
runtimeSignalEvaluations: (userName: string) => string;
|
|
52
|
+
runtimeSignalEvaluation: (userName: string, evaluationId: string) => string;
|
|
53
|
+
runtimeSignalEvaluationBuckets: (userName: string) => string;
|
|
54
|
+
runtimeSignalEvaluationBucket: (userName: string, dayKey: string, strategyName: string) => string;
|
|
55
|
+
runtimeSignalEvaluationStatsBuckets: (userName: string) => string;
|
|
56
|
+
runtimeSignalEvaluationStatsBucket: (userName: string, dayKey: string, strategyName: string) => string;
|
|
57
|
+
runtimeTrades: (userName: string) => string;
|
|
58
|
+
runtimeTrade: (userName: string, orderId: string) => string;
|
|
59
|
+
runtimeActiveTrades: (userName: string) => string;
|
|
60
|
+
runtimeActiveTrade: (userName: string, symbol: string) => string;
|
|
61
|
+
aiChatHistory: (userName: string, symbolKey: string) => string;
|
|
40
62
|
analysis: (symbol: string, signalId: string) => string;
|
|
63
|
+
screenshotSessionToken: (token: string) => string;
|
|
41
64
|
backtestResults: (userName: string, config: string, timestamp: string) => string;
|
|
65
|
+
researchRuns: (userName: string) => string;
|
|
66
|
+
researchRun: (userName: string, runId: string) => string;
|
|
67
|
+
researchLatestRun: (userName: string, strategyName: string) => string;
|
|
42
68
|
mlSignalsByStrategy: (strategyName: string) => string;
|
|
43
69
|
mlSignals: () => string;
|
|
44
70
|
mlSignal: (strategyName: string, signalId: string) => string;
|
|
@@ -47,4 +73,4 @@ declare const redisKeys: {
|
|
|
47
73
|
mlResult: (strategyName: string, signalId: string) => string;
|
|
48
74
|
};
|
|
49
75
|
|
|
50
|
-
export { RedisWriteBlockedError, delKey, delKeyWithOptions, getData, getKeys, redisKeys, setData };
|
|
76
|
+
export { RedisWriteBlockedError, consumeScreenshotSessionToken, createScreenshotSessionToken, delKey, delKeyWithOptions, getData, getHashData, getHashJsonValues, getKeys, incrHashFields, redisKeys, setData, setHashJsonField };
|
package/dist/redis.d.ts
CHANGED
|
@@ -17,6 +17,12 @@ declare class RedisWriteBlockedError extends Error {
|
|
|
17
17
|
}
|
|
18
18
|
declare const delKeyWithOptions: (key: string, options?: DelKeyOptions) => Promise<boolean>;
|
|
19
19
|
declare const setData: <T>(key: string, data: T, options?: Options) => Promise<void>;
|
|
20
|
+
declare const setHashJsonField: <T>(key: string, field: string, data: T, options?: Options) => Promise<void>;
|
|
21
|
+
declare const getHashJsonValues: <T>(key: string) => Promise<T[]>;
|
|
22
|
+
declare const incrHashFields: (key: string, increments: Record<string, number>, options?: Options) => Promise<void>;
|
|
23
|
+
declare const getHashData: (key: string) => Promise<Record<string, string>>;
|
|
24
|
+
declare const createScreenshotSessionToken: (userName: string) => Promise<string | null>;
|
|
25
|
+
declare const consumeScreenshotSessionToken: (token: string) => Promise<string | null>;
|
|
20
26
|
declare const redisKeys: {
|
|
21
27
|
users: () => string;
|
|
22
28
|
user: (userName: string) => string;
|
|
@@ -31,14 +37,34 @@ declare const redisKeys: {
|
|
|
31
37
|
testOrders: (userName: string, strategyName: string, testName: string) => string;
|
|
32
38
|
testConfig: (userName: string, strategyName: string, testName: string) => string;
|
|
33
39
|
testStat: (userName: string, strategyName: string, testName: string) => string;
|
|
40
|
+
testSummaries: (userName: string) => string;
|
|
34
41
|
cacheChunk: (userName: string, chunkId: string) => string;
|
|
35
42
|
cacheOrders: (userName: string, orderLogId: string) => string;
|
|
36
43
|
cachePositions: (userName: string, orderLogId: string) => string;
|
|
37
44
|
signal: (symbol: string, signalId: string) => string;
|
|
38
45
|
signalsBySymbol: (symbol: string) => string;
|
|
39
46
|
storeSignal: (symbol: string, signalId: string) => string;
|
|
47
|
+
runtimeSignals: (userName: string) => string;
|
|
48
|
+
runtimeSignal: (userName: string, signalId: string) => string;
|
|
49
|
+
runtimeSignalBuckets: (userName: string) => string;
|
|
50
|
+
runtimeSignalBucket: (userName: string, dayKey: string, strategyName: string) => string;
|
|
51
|
+
runtimeSignalEvaluations: (userName: string) => string;
|
|
52
|
+
runtimeSignalEvaluation: (userName: string, evaluationId: string) => string;
|
|
53
|
+
runtimeSignalEvaluationBuckets: (userName: string) => string;
|
|
54
|
+
runtimeSignalEvaluationBucket: (userName: string, dayKey: string, strategyName: string) => string;
|
|
55
|
+
runtimeSignalEvaluationStatsBuckets: (userName: string) => string;
|
|
56
|
+
runtimeSignalEvaluationStatsBucket: (userName: string, dayKey: string, strategyName: string) => string;
|
|
57
|
+
runtimeTrades: (userName: string) => string;
|
|
58
|
+
runtimeTrade: (userName: string, orderId: string) => string;
|
|
59
|
+
runtimeActiveTrades: (userName: string) => string;
|
|
60
|
+
runtimeActiveTrade: (userName: string, symbol: string) => string;
|
|
61
|
+
aiChatHistory: (userName: string, symbolKey: string) => string;
|
|
40
62
|
analysis: (symbol: string, signalId: string) => string;
|
|
63
|
+
screenshotSessionToken: (token: string) => string;
|
|
41
64
|
backtestResults: (userName: string, config: string, timestamp: string) => string;
|
|
65
|
+
researchRuns: (userName: string) => string;
|
|
66
|
+
researchRun: (userName: string, runId: string) => string;
|
|
67
|
+
researchLatestRun: (userName: string, strategyName: string) => string;
|
|
42
68
|
mlSignalsByStrategy: (strategyName: string) => string;
|
|
43
69
|
mlSignals: () => string;
|
|
44
70
|
mlSignal: (strategyName: string, signalId: string) => string;
|
|
@@ -47,4 +73,4 @@ declare const redisKeys: {
|
|
|
47
73
|
mlResult: (strategyName: string, signalId: string) => string;
|
|
48
74
|
};
|
|
49
75
|
|
|
50
|
-
export { RedisWriteBlockedError, delKey, delKeyWithOptions, getData, getKeys, redisKeys, setData };
|
|
76
|
+
export { RedisWriteBlockedError, consumeScreenshotSessionToken, createScreenshotSessionToken, delKey, delKeyWithOptions, getData, getHashData, getHashJsonValues, getKeys, incrHashFields, redisKeys, setData, setHashJsonField };
|
package/dist/redis.js
CHANGED
|
@@ -31,16 +31,24 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var redis_exports = {};
|
|
32
32
|
__export(redis_exports, {
|
|
33
33
|
RedisWriteBlockedError: () => RedisWriteBlockedError,
|
|
34
|
+
consumeScreenshotSessionToken: () => consumeScreenshotSessionToken,
|
|
35
|
+
createScreenshotSessionToken: () => createScreenshotSessionToken,
|
|
34
36
|
delKey: () => delKey,
|
|
35
37
|
delKeyWithOptions: () => delKeyWithOptions,
|
|
36
38
|
getData: () => getData,
|
|
39
|
+
getHashData: () => getHashData,
|
|
40
|
+
getHashJsonValues: () => getHashJsonValues,
|
|
37
41
|
getKeys: () => getKeys,
|
|
42
|
+
incrHashFields: () => incrHashFields,
|
|
38
43
|
redisKeys: () => redisKeys,
|
|
39
|
-
setData: () => setData
|
|
44
|
+
setData: () => setData,
|
|
45
|
+
setHashJsonField: () => setHashJsonField
|
|
40
46
|
});
|
|
41
47
|
module.exports = __toCommonJS(redis_exports);
|
|
48
|
+
var import_crypto = require("crypto");
|
|
42
49
|
var import_ioredis = __toESM(require("ioredis"));
|
|
43
50
|
var TTL_1D = 86400;
|
|
51
|
+
var SCREENSHOT_TOKEN_TTL_SECONDS = 15 * 60;
|
|
44
52
|
var toJson = (value) => JSON.stringify(value);
|
|
45
53
|
var logger = {
|
|
46
54
|
log: (level, message, ...args) => {
|
|
@@ -160,6 +168,31 @@ var parseJsonOrDeleteKey = async (redis, key, raw, fallback) => {
|
|
|
160
168
|
return fallback;
|
|
161
169
|
}
|
|
162
170
|
};
|
|
171
|
+
var parseHashMap = (value) => {
|
|
172
|
+
if (!value) {
|
|
173
|
+
return {};
|
|
174
|
+
}
|
|
175
|
+
if (Array.isArray(value)) {
|
|
176
|
+
const result = {};
|
|
177
|
+
for (let index = 0; index < value.length; index += 2) {
|
|
178
|
+
const field = value[index];
|
|
179
|
+
const fieldValue = value[index + 1];
|
|
180
|
+
if (field == null || fieldValue == null) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
result[String(field)] = toResultString(fieldValue) ?? "";
|
|
184
|
+
}
|
|
185
|
+
return result;
|
|
186
|
+
}
|
|
187
|
+
if (typeof value === "object") {
|
|
188
|
+
return Object.fromEntries(
|
|
189
|
+
Object.entries(value).map(
|
|
190
|
+
([field, fieldValue]) => [field, toResultString(fieldValue) ?? ""]
|
|
191
|
+
)
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
return {};
|
|
195
|
+
};
|
|
163
196
|
var getKeys = async (prefix) => {
|
|
164
197
|
if (redisUnavailable) return [];
|
|
165
198
|
const redis = await getReadyRedis();
|
|
@@ -296,6 +329,126 @@ var setData = async (key, data, options = {}) => {
|
|
|
296
329
|
}
|
|
297
330
|
}
|
|
298
331
|
};
|
|
332
|
+
var setHashJsonField = async (key, field, data, options = {}) => {
|
|
333
|
+
if (redisUnavailable) return;
|
|
334
|
+
const { expire } = { ...DEFAULT_OPTIONS, ...options };
|
|
335
|
+
const redis = await getReadyRedis();
|
|
336
|
+
if (!redis) return;
|
|
337
|
+
try {
|
|
338
|
+
await redis.call("HSET", key, field, toJson(data));
|
|
339
|
+
if (expire) {
|
|
340
|
+
await redis.expire(key, expire);
|
|
341
|
+
}
|
|
342
|
+
} catch (e) {
|
|
343
|
+
if (e instanceof Error && isRedisConnectivityError(e)) {
|
|
344
|
+
markRedisUnavailable(e);
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
logger.log("error", "failed HSET %s[%s]: %s", key, field, String(e));
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
var getHashJsonValues = async (key) => {
|
|
351
|
+
if (redisUnavailable) return [];
|
|
352
|
+
const redis = await getReadyRedis();
|
|
353
|
+
if (!redis) return [];
|
|
354
|
+
try {
|
|
355
|
+
const raw = await redis.call("HGETALL", key);
|
|
356
|
+
const values = Object.values(parseHashMap(raw));
|
|
357
|
+
const parsed = [];
|
|
358
|
+
for (const value of values) {
|
|
359
|
+
if (!value) {
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
try {
|
|
363
|
+
parsed.push(JSON.parse(value));
|
|
364
|
+
} catch (e) {
|
|
365
|
+
logger.log(
|
|
366
|
+
"error",
|
|
367
|
+
"failed JSON.parse(HGETALL %s value): %s",
|
|
368
|
+
key,
|
|
369
|
+
String(e)
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return parsed;
|
|
374
|
+
} catch (e) {
|
|
375
|
+
if (e instanceof Error && isRedisConnectivityError(e)) {
|
|
376
|
+
markRedisUnavailable(e);
|
|
377
|
+
return [];
|
|
378
|
+
}
|
|
379
|
+
logger.log("error", "failed HGETALL %s: %s", key, String(e));
|
|
380
|
+
return [];
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
var incrHashFields = async (key, increments, options = {}) => {
|
|
384
|
+
if (redisUnavailable) return;
|
|
385
|
+
const { expire } = { ...DEFAULT_OPTIONS, ...options };
|
|
386
|
+
const redis = await getReadyRedis();
|
|
387
|
+
if (!redis) return;
|
|
388
|
+
try {
|
|
389
|
+
for (const [field, increment] of Object.entries(increments)) {
|
|
390
|
+
if (!Number.isFinite(increment) || increment === 0) {
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
await redis.call("HINCRBY", key, field, Math.trunc(increment));
|
|
394
|
+
}
|
|
395
|
+
if (expire) {
|
|
396
|
+
await redis.expire(key, expire);
|
|
397
|
+
}
|
|
398
|
+
} catch (e) {
|
|
399
|
+
if (e instanceof Error && isRedisConnectivityError(e)) {
|
|
400
|
+
markRedisUnavailable(e);
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
logger.log("error", "failed HINCRBY %s: %s", key, String(e));
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
var getHashData = async (key) => {
|
|
407
|
+
if (redisUnavailable) return {};
|
|
408
|
+
const redis = await getReadyRedis();
|
|
409
|
+
if (!redis) return {};
|
|
410
|
+
try {
|
|
411
|
+
const raw = await redis.call("HGETALL", key);
|
|
412
|
+
return parseHashMap(raw);
|
|
413
|
+
} catch (e) {
|
|
414
|
+
if (e instanceof Error && isRedisConnectivityError(e)) {
|
|
415
|
+
markRedisUnavailable(e);
|
|
416
|
+
return {};
|
|
417
|
+
}
|
|
418
|
+
logger.log("error", "failed HGETALL %s: %s", key, String(e));
|
|
419
|
+
return {};
|
|
420
|
+
}
|
|
421
|
+
};
|
|
422
|
+
var createScreenshotSessionToken = async (userName) => {
|
|
423
|
+
const token = (0, import_crypto.randomBytes)(24).toString("hex");
|
|
424
|
+
await setData(
|
|
425
|
+
redisKeys.screenshotSessionToken(token),
|
|
426
|
+
{
|
|
427
|
+
userName,
|
|
428
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
expire: SCREENSHOT_TOKEN_TTL_SECONDS
|
|
432
|
+
}
|
|
433
|
+
);
|
|
434
|
+
return token;
|
|
435
|
+
};
|
|
436
|
+
var consumeScreenshotSessionToken = async (token) => {
|
|
437
|
+
const normalizedToken = token.trim();
|
|
438
|
+
if (!normalizedToken) {
|
|
439
|
+
return null;
|
|
440
|
+
}
|
|
441
|
+
const key = redisKeys.screenshotSessionToken(normalizedToken);
|
|
442
|
+
const payload = await getData(
|
|
443
|
+
key,
|
|
444
|
+
null
|
|
445
|
+
);
|
|
446
|
+
if (!payload?.userName) {
|
|
447
|
+
return null;
|
|
448
|
+
}
|
|
449
|
+
await delKey(key);
|
|
450
|
+
return payload.userName;
|
|
451
|
+
};
|
|
299
452
|
var redisKeys = {
|
|
300
453
|
users: () => "users:index:",
|
|
301
454
|
user: (userName) => `users:index:${userName}`,
|
|
@@ -310,14 +463,34 @@ var redisKeys = {
|
|
|
310
463
|
testOrders: (userName, strategyName, testName) => `users:${userName}:tests:${strategyName}:${testName}:orders`,
|
|
311
464
|
testConfig: (userName, strategyName, testName) => `users:${userName}:tests:${strategyName}:${testName}:config`,
|
|
312
465
|
testStat: (userName, strategyName, testName) => `users:${userName}:tests:${strategyName}:${testName}:stat`,
|
|
466
|
+
testSummaries: (userName) => `users:${userName}:tests:index:summary`,
|
|
313
467
|
cacheChunk: (userName, chunkId) => `users:${userName}:cache:tests:chunks:${chunkId}`,
|
|
314
468
|
cacheOrders: (userName, orderLogId) => `users:${userName}:cache:tests:orders:${orderLogId}`,
|
|
315
469
|
cachePositions: (userName, orderLogId) => `users:${userName}:cache:tests:positions:${orderLogId}`,
|
|
316
470
|
signal: (symbol, signalId) => `signals:${symbol}:${signalId}`,
|
|
317
471
|
signalsBySymbol: (symbol) => `signals:${symbol}:`,
|
|
318
472
|
storeSignal: (symbol, signalId) => `store:signals:${symbol}:${signalId}`,
|
|
473
|
+
runtimeSignals: (userName) => `users:${userName}:runtime:signals:`,
|
|
474
|
+
runtimeSignal: (userName, signalId) => `users:${userName}:runtime:signals:${signalId}`,
|
|
475
|
+
runtimeSignalBuckets: (userName) => `users:${userName}:runtime:signals:days:`,
|
|
476
|
+
runtimeSignalBucket: (userName, dayKey, strategyName) => `users:${userName}:runtime:signals:days:${dayKey}:${strategyName}`,
|
|
477
|
+
runtimeSignalEvaluations: (userName) => `users:${userName}:runtime:signal-evaluations:`,
|
|
478
|
+
runtimeSignalEvaluation: (userName, evaluationId) => `users:${userName}:runtime:signal-evaluations:${evaluationId}`,
|
|
479
|
+
runtimeSignalEvaluationBuckets: (userName) => `users:${userName}:runtime:signal-evaluations:days:`,
|
|
480
|
+
runtimeSignalEvaluationBucket: (userName, dayKey, strategyName) => `users:${userName}:runtime:signal-evaluations:days:${dayKey}:${strategyName}`,
|
|
481
|
+
runtimeSignalEvaluationStatsBuckets: (userName) => `users:${userName}:runtime:signal-evaluation-stats:days:`,
|
|
482
|
+
runtimeSignalEvaluationStatsBucket: (userName, dayKey, strategyName) => `users:${userName}:runtime:signal-evaluation-stats:days:${dayKey}:${strategyName}`,
|
|
483
|
+
runtimeTrades: (userName) => `users:${userName}:runtime:trade-records:`,
|
|
484
|
+
runtimeTrade: (userName, orderId) => `users:${userName}:runtime:trade-records:${orderId}`,
|
|
485
|
+
runtimeActiveTrades: (userName) => `users:${userName}:runtime:active-trades:`,
|
|
486
|
+
runtimeActiveTrade: (userName, symbol) => `users:${userName}:runtime:active-trades:${symbol}`,
|
|
487
|
+
aiChatHistory: (userName, symbolKey) => `users:${userName}:ai:chats:${symbolKey}`,
|
|
319
488
|
analysis: (symbol, signalId) => `analysis:${symbol}:${signalId}`,
|
|
489
|
+
screenshotSessionToken: (token) => `auth:screenshot:${token}`,
|
|
320
490
|
backtestResults: (userName, config, timestamp) => `users:${userName}:backtests:results:${config}:${timestamp}`,
|
|
491
|
+
researchRuns: (userName) => `users:${userName}:research:runs:`,
|
|
492
|
+
researchRun: (userName, runId) => `users:${userName}:research:runs:${runId}`,
|
|
493
|
+
researchLatestRun: (userName, strategyName) => `users:${userName}:research:latest:${strategyName}`,
|
|
321
494
|
mlSignalsByStrategy: (strategyName) => `ml:${strategyName}:signals:`,
|
|
322
495
|
mlSignals: () => "ml:",
|
|
323
496
|
mlSignal: (strategyName, signalId) => `ml:${strategyName}:signals:${signalId}`,
|
|
@@ -328,10 +501,16 @@ var redisKeys = {
|
|
|
328
501
|
// Annotate the CommonJS export names for ESM import in node:
|
|
329
502
|
0 && (module.exports = {
|
|
330
503
|
RedisWriteBlockedError,
|
|
504
|
+
consumeScreenshotSessionToken,
|
|
505
|
+
createScreenshotSessionToken,
|
|
331
506
|
delKey,
|
|
332
507
|
delKeyWithOptions,
|
|
333
508
|
getData,
|
|
509
|
+
getHashData,
|
|
510
|
+
getHashJsonValues,
|
|
334
511
|
getKeys,
|
|
512
|
+
incrHashFields,
|
|
335
513
|
redisKeys,
|
|
336
|
-
setData
|
|
514
|
+
setData,
|
|
515
|
+
setHashJsonField
|
|
337
516
|
});
|
package/dist/redis.mjs
CHANGED
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
import {
|
|
2
2
|
RedisWriteBlockedError,
|
|
3
|
+
consumeScreenshotSessionToken,
|
|
4
|
+
createScreenshotSessionToken,
|
|
3
5
|
delKey,
|
|
4
6
|
delKeyWithOptions,
|
|
5
7
|
getData,
|
|
8
|
+
getHashData,
|
|
9
|
+
getHashJsonValues,
|
|
6
10
|
getKeys,
|
|
11
|
+
incrHashFields,
|
|
7
12
|
redisKeys,
|
|
8
|
-
setData
|
|
9
|
-
|
|
13
|
+
setData,
|
|
14
|
+
setHashJsonField
|
|
15
|
+
} from "./chunk-MLVWC2I2.mjs";
|
|
10
16
|
export {
|
|
11
17
|
RedisWriteBlockedError,
|
|
18
|
+
consumeScreenshotSessionToken,
|
|
19
|
+
createScreenshotSessionToken,
|
|
12
20
|
delKey,
|
|
13
21
|
delKeyWithOptions,
|
|
14
22
|
getData,
|
|
23
|
+
getHashData,
|
|
24
|
+
getHashJsonValues,
|
|
15
25
|
getKeys,
|
|
26
|
+
incrHashFields,
|
|
16
27
|
redisKeys,
|
|
17
|
-
setData
|
|
28
|
+
setData,
|
|
29
|
+
setHashJsonField
|
|
18
30
|
};
|
package/dist/timescale.d.mts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Pool } from 'pg';
|
|
2
|
-
import { DerivativesInterval,
|
|
2
|
+
import { DerivativesInterval, DerivativesRow, KlineChartData, SpreadRow } from '@tradejs/types';
|
|
3
3
|
|
|
4
4
|
declare global {
|
|
5
5
|
var __pgPool__: Pool | undefined;
|
|
6
6
|
}
|
|
7
7
|
type CandleRow = {
|
|
8
|
+
provider: string;
|
|
8
9
|
symbol: string;
|
|
9
10
|
interval: number;
|
|
10
11
|
ts: Date;
|
|
@@ -15,10 +16,20 @@ type CandleRow = {
|
|
|
15
16
|
volume?: number | null;
|
|
16
17
|
turnover?: number | null;
|
|
17
18
|
};
|
|
18
|
-
declare const toRows: (symbol: string, interval: number, data: KlineChartData) => CandleRow[];
|
|
19
|
+
declare const toRows: (provider: string, symbol: string, interval: number, data: KlineChartData) => CandleRow[];
|
|
19
20
|
declare function upsertCandles(rows: CandleRow[]): Promise<void>;
|
|
20
21
|
declare function upsertDerivatives(rows: DerivativesRow[]): Promise<void>;
|
|
21
22
|
declare function getDerivativesRangeForSymbols(symbols: string[], interval: DerivativesInterval, startMs: number, endMs: number): Promise<any[]>;
|
|
23
|
+
declare function getDerivativesDataEdgesForSymbols(symbols: string[], interval: DerivativesInterval): Promise<Map<string, {
|
|
24
|
+
min?: number;
|
|
25
|
+
max?: number;
|
|
26
|
+
}>>;
|
|
27
|
+
declare function getDerivativesWindow(params: {
|
|
28
|
+
symbol: string;
|
|
29
|
+
intervals: DerivativesInterval[];
|
|
30
|
+
endMs: number;
|
|
31
|
+
lookbackMs: number;
|
|
32
|
+
}): Promise<Partial<Record<DerivativesInterval, DerivativesRow[]>>>;
|
|
22
33
|
declare function getDerivativesSummary(hours?: number, limit?: number): Promise<{
|
|
23
34
|
rows: any[];
|
|
24
35
|
aggregates: any[];
|
|
@@ -31,17 +42,17 @@ declare function getSpreadSummary(hours?: number, limit?: number): Promise<{
|
|
|
31
42
|
aggregates: any[];
|
|
32
43
|
hours: number;
|
|
33
44
|
}>;
|
|
34
|
-
declare function getCandlesRange(symbol: string, interval: number, startMs: number, endMs: number): Promise<any[]>;
|
|
35
|
-
declare function getDataEdges(symbol: string, interval: number): Promise<{
|
|
45
|
+
declare function getCandlesRange(provider: string, symbol: string, interval: number, startMs: number, endMs: number): Promise<any[]>;
|
|
46
|
+
declare function getDataEdges(provider: string, symbol: string, interval: number): Promise<{
|
|
36
47
|
min: number | undefined;
|
|
37
48
|
max: number | undefined;
|
|
38
49
|
}>;
|
|
39
50
|
declare function waitForDbReady(attempts?: number, delayMs?: number): Promise<void>;
|
|
40
|
-
declare function deleteCandles(symbol: string, interval: number): Promise<void>;
|
|
41
|
-
declare function findContinuityGap(symbol: string, interval: number): Promise<{
|
|
51
|
+
declare function deleteCandles(provider: string, symbol: string, interval: number): Promise<void>;
|
|
52
|
+
declare function findContinuityGap(provider: string, symbol: string, interval: number): Promise<{
|
|
42
53
|
ts: number;
|
|
43
54
|
prevTs: number;
|
|
44
55
|
diffSeconds: number;
|
|
45
56
|
} | null>;
|
|
46
57
|
|
|
47
|
-
export { type CandleRow, deleteCandles, findContinuityGap, getCandlesRange, getDataEdges, getDerivativesRangeForSymbols, getDerivativesSummary, getSpreadRangeForSymbols, getSpreadSummary, toRows, upsertCandles, upsertDerivatives, upsertSpreadRows, waitForDbReady };
|
|
58
|
+
export { type CandleRow, deleteCandles, findContinuityGap, getCandlesRange, getDataEdges, getDerivativesDataEdgesForSymbols, getDerivativesRangeForSymbols, getDerivativesSummary, getDerivativesWindow, getSpreadRangeForSymbols, getSpreadSummary, toRows, upsertCandles, upsertDerivatives, upsertSpreadRows, waitForDbReady };
|
package/dist/timescale.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Pool } from 'pg';
|
|
2
|
-
import { DerivativesInterval,
|
|
2
|
+
import { DerivativesInterval, DerivativesRow, KlineChartData, SpreadRow } from '@tradejs/types';
|
|
3
3
|
|
|
4
4
|
declare global {
|
|
5
5
|
var __pgPool__: Pool | undefined;
|
|
6
6
|
}
|
|
7
7
|
type CandleRow = {
|
|
8
|
+
provider: string;
|
|
8
9
|
symbol: string;
|
|
9
10
|
interval: number;
|
|
10
11
|
ts: Date;
|
|
@@ -15,10 +16,20 @@ type CandleRow = {
|
|
|
15
16
|
volume?: number | null;
|
|
16
17
|
turnover?: number | null;
|
|
17
18
|
};
|
|
18
|
-
declare const toRows: (symbol: string, interval: number, data: KlineChartData) => CandleRow[];
|
|
19
|
+
declare const toRows: (provider: string, symbol: string, interval: number, data: KlineChartData) => CandleRow[];
|
|
19
20
|
declare function upsertCandles(rows: CandleRow[]): Promise<void>;
|
|
20
21
|
declare function upsertDerivatives(rows: DerivativesRow[]): Promise<void>;
|
|
21
22
|
declare function getDerivativesRangeForSymbols(symbols: string[], interval: DerivativesInterval, startMs: number, endMs: number): Promise<any[]>;
|
|
23
|
+
declare function getDerivativesDataEdgesForSymbols(symbols: string[], interval: DerivativesInterval): Promise<Map<string, {
|
|
24
|
+
min?: number;
|
|
25
|
+
max?: number;
|
|
26
|
+
}>>;
|
|
27
|
+
declare function getDerivativesWindow(params: {
|
|
28
|
+
symbol: string;
|
|
29
|
+
intervals: DerivativesInterval[];
|
|
30
|
+
endMs: number;
|
|
31
|
+
lookbackMs: number;
|
|
32
|
+
}): Promise<Partial<Record<DerivativesInterval, DerivativesRow[]>>>;
|
|
22
33
|
declare function getDerivativesSummary(hours?: number, limit?: number): Promise<{
|
|
23
34
|
rows: any[];
|
|
24
35
|
aggregates: any[];
|
|
@@ -31,17 +42,17 @@ declare function getSpreadSummary(hours?: number, limit?: number): Promise<{
|
|
|
31
42
|
aggregates: any[];
|
|
32
43
|
hours: number;
|
|
33
44
|
}>;
|
|
34
|
-
declare function getCandlesRange(symbol: string, interval: number, startMs: number, endMs: number): Promise<any[]>;
|
|
35
|
-
declare function getDataEdges(symbol: string, interval: number): Promise<{
|
|
45
|
+
declare function getCandlesRange(provider: string, symbol: string, interval: number, startMs: number, endMs: number): Promise<any[]>;
|
|
46
|
+
declare function getDataEdges(provider: string, symbol: string, interval: number): Promise<{
|
|
36
47
|
min: number | undefined;
|
|
37
48
|
max: number | undefined;
|
|
38
49
|
}>;
|
|
39
50
|
declare function waitForDbReady(attempts?: number, delayMs?: number): Promise<void>;
|
|
40
|
-
declare function deleteCandles(symbol: string, interval: number): Promise<void>;
|
|
41
|
-
declare function findContinuityGap(symbol: string, interval: number): Promise<{
|
|
51
|
+
declare function deleteCandles(provider: string, symbol: string, interval: number): Promise<void>;
|
|
52
|
+
declare function findContinuityGap(provider: string, symbol: string, interval: number): Promise<{
|
|
42
53
|
ts: number;
|
|
43
54
|
prevTs: number;
|
|
44
55
|
diffSeconds: number;
|
|
45
56
|
} | null>;
|
|
46
57
|
|
|
47
|
-
export { type CandleRow, deleteCandles, findContinuityGap, getCandlesRange, getDataEdges, getDerivativesRangeForSymbols, getDerivativesSummary, getSpreadRangeForSymbols, getSpreadSummary, toRows, upsertCandles, upsertDerivatives, upsertSpreadRows, waitForDbReady };
|
|
58
|
+
export { type CandleRow, deleteCandles, findContinuityGap, getCandlesRange, getDataEdges, getDerivativesDataEdgesForSymbols, getDerivativesRangeForSymbols, getDerivativesSummary, getDerivativesWindow, getSpreadRangeForSymbols, getSpreadSummary, toRows, upsertCandles, upsertDerivatives, upsertSpreadRows, waitForDbReady };
|