@tradejs/node 3.1.18 → 3.1.19-beta.233
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/runtimeDashboard.js +44 -37
- package/dist/runtimeDashboard.mjs +44 -37
- package/package.json +5 -5
package/dist/runtimeDashboard.js
CHANGED
|
@@ -7764,26 +7764,52 @@ var loadRuntimeTrades = async (userName, {
|
|
|
7764
7764
|
}) => {
|
|
7765
7765
|
const filterByWindow = (trade) => trade.entryTimestamp >= startTime || typeof trade.exitTimestamp === "number" && trade.exitTimestamp >= startTime;
|
|
7766
7766
|
const dayKeys = (0, import_time4.getRuntimeStorageDayKeys)(startTime, endTime);
|
|
7767
|
-
const
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7767
|
+
const [bucketTradeGroups, legacyKeys] = await Promise.all([
|
|
7768
|
+
Promise.all(
|
|
7769
|
+
dayKeys.map(
|
|
7770
|
+
(dayKey) => (0, import_redis4.getHashJsonValues)(
|
|
7771
|
+
import_redis4.redisKeys.runtimeTradeBucket(userName, dayKey)
|
|
7772
|
+
)
|
|
7771
7773
|
)
|
|
7772
|
-
)
|
|
7773
|
-
|
|
7774
|
-
|
|
7775
|
-
|
|
7774
|
+
),
|
|
7775
|
+
(0, import_redis4.getKeys)(import_redis4.redisKeys.runtimeTrades(userName))
|
|
7776
|
+
]);
|
|
7777
|
+
const legacyTradeKeys = legacyKeys.filter(
|
|
7778
|
+
(key) => !key.startsWith(import_redis4.redisKeys.runtimeTradeBuckets(userName))
|
|
7779
|
+
);
|
|
7780
|
+
const legacyTrades = await Promise.all(
|
|
7781
|
+
legacyTradeKeys.map((key) => (0, import_redis4.getData)(key, null))
|
|
7782
|
+
);
|
|
7783
|
+
const dedupedTrades = /* @__PURE__ */ new Map();
|
|
7784
|
+
for (const trade of [...legacyTrades, ...bucketTradeGroups.flat()]) {
|
|
7776
7785
|
if (!(0, import_runtimeTrades3.isRuntimeTradeRecord)(trade)) {
|
|
7777
7786
|
continue;
|
|
7778
7787
|
}
|
|
7779
|
-
|
|
7788
|
+
const existing = dedupedTrades.get(trade.orderId);
|
|
7789
|
+
if (!existing || (trade.lastSyncedAt ?? Number.NEGATIVE_INFINITY) >= (existing.lastSyncedAt ?? Number.NEGATIVE_INFINITY)) {
|
|
7790
|
+
dedupedTrades.set(trade.orderId, trade);
|
|
7791
|
+
}
|
|
7780
7792
|
}
|
|
7781
|
-
|
|
7782
|
-
|
|
7793
|
+
return [...dedupedTrades.values()].filter(filterByWindow).sort((left, right) => left.entryTimestamp - right.entryTimestamp);
|
|
7794
|
+
};
|
|
7795
|
+
var getTradeStrategyRevision = (trade) => trade.strategyRevision ?? (trade.runtimeLineage?.schemaVersion === 3 ? trade.runtimeLineage.strategyRevision : void 0);
|
|
7796
|
+
var buildStrategyRevisionChanges = (trades) => {
|
|
7797
|
+
const changes = [];
|
|
7798
|
+
let previousRevision;
|
|
7799
|
+
for (const trade of [...trades].sort(
|
|
7800
|
+
(left, right) => left.entryTimestamp - right.entryTimestamp || left.orderId.localeCompare(right.orderId)
|
|
7801
|
+
)) {
|
|
7802
|
+
const strategyRevision = getTradeStrategyRevision(trade);
|
|
7803
|
+
if (!strategyRevision) continue;
|
|
7804
|
+
if (previousRevision && strategyRevision !== previousRevision) {
|
|
7805
|
+
changes.push({
|
|
7806
|
+
timestamp: trade.entryTimestamp,
|
|
7807
|
+
strategyRevision
|
|
7808
|
+
});
|
|
7809
|
+
}
|
|
7810
|
+
previousRevision = strategyRevision;
|
|
7783
7811
|
}
|
|
7784
|
-
|
|
7785
|
-
const trades = await Promise.all(keys.map((key) => (0, import_redis4.getData)(key, null)));
|
|
7786
|
-
return trades.filter(import_runtimeTrades3.isRuntimeTradeRecord).filter(filterByWindow).sort((left, right) => left.entryTimestamp - right.entryTimestamp);
|
|
7812
|
+
return changes;
|
|
7787
7813
|
};
|
|
7788
7814
|
var buildExchangeTimeRanges = (startTime, endTime) => {
|
|
7789
7815
|
const ranges = [];
|
|
@@ -8024,14 +8050,6 @@ var loadRuntimeDashboard = async ({
|
|
|
8024
8050
|
)
|
|
8025
8051
|
)
|
|
8026
8052
|
);
|
|
8027
|
-
const runtimeIdentityKey = (trade) => (0, import_runtimeTrades3.buildRuntimeStrategyIdentityKey)({
|
|
8028
|
-
strategyName: trade.strategy,
|
|
8029
|
-
configId: trade.strategyRevision,
|
|
8030
|
-
universe: trade.universe,
|
|
8031
|
-
accountId: trade.accountId,
|
|
8032
|
-
deploymentId: trade.deploymentId,
|
|
8033
|
-
policyProfileId: trade.policyProfileId
|
|
8034
|
-
});
|
|
8035
8053
|
const identityByKey = /* @__PURE__ */ new Map();
|
|
8036
8054
|
for (const deployment of runtimeDeployments) {
|
|
8037
8055
|
for (const resolvedStrategy of resolvedStrategiesByDeployment.get(
|
|
@@ -8067,24 +8085,12 @@ var loadRuntimeDashboard = async ({
|
|
|
8067
8085
|
});
|
|
8068
8086
|
}
|
|
8069
8087
|
}
|
|
8070
|
-
const accountScopedTrades = allTrades;
|
|
8071
|
-
for (const trade of accountScopedTrades) {
|
|
8072
|
-
const key = runtimeIdentityKey(trade);
|
|
8073
|
-
const configuredIdentity = identityByKey.get(key);
|
|
8074
|
-
if (!configuredIdentity) continue;
|
|
8075
|
-
const strategyRevision = trade.strategyRevision ?? (trade.runtimeLineage?.schemaVersion === 3 ? trade.runtimeLineage.strategyRevision : void 0);
|
|
8076
|
-
if (strategyRevision !== configuredIdentity.strategyRevision) continue;
|
|
8077
|
-
identityByKey.set(key, {
|
|
8078
|
-
...configuredIdentity,
|
|
8079
|
-
interval: String(
|
|
8080
|
-
trade.interval ?? configuredIdentity.interval
|
|
8081
|
-
)
|
|
8082
|
-
});
|
|
8083
|
-
}
|
|
8084
8088
|
const strategies2 = await Promise.all(
|
|
8085
8089
|
[...identityByKey.entries()].map(async ([runtimeKey, identity]) => {
|
|
8086
8090
|
const { strategyName } = identity;
|
|
8087
|
-
const strategyTrades =
|
|
8091
|
+
const strategyTrades = allTrades.filter(
|
|
8092
|
+
(trade) => trade.strategy === strategyName && String(trade.interval) === String(identity.interval)
|
|
8093
|
+
).sort((left, right) => right.entryTimestamp - left.entryTimestamp);
|
|
8088
8094
|
const orders = strategyTrades.sort((left, right) => {
|
|
8089
8095
|
const leftDate = left.exitTimestamp ?? left.entryTimestamp;
|
|
8090
8096
|
const rightDate = right.exitTimestamp ?? right.entryTimestamp;
|
|
@@ -8116,6 +8122,7 @@ var loadRuntimeDashboard = async ({
|
|
|
8116
8122
|
stat: analytics.stat,
|
|
8117
8123
|
summary: analytics.summary,
|
|
8118
8124
|
orderLog: analytics.orderLog,
|
|
8125
|
+
revisionChanges: buildStrategyRevisionChanges(strategyTrades),
|
|
8119
8126
|
recentTrades: strategyTrades.slice(0, 8).map((trade) => (0, import_runtimeTrades3.toRuntimeTradeView)(trade, endTime)),
|
|
8120
8127
|
orders
|
|
8121
8128
|
};
|
|
@@ -271,26 +271,52 @@ var loadRuntimeTrades = async (userName, {
|
|
|
271
271
|
}) => {
|
|
272
272
|
const filterByWindow = (trade) => trade.entryTimestamp >= startTime || typeof trade.exitTimestamp === "number" && trade.exitTimestamp >= startTime;
|
|
273
273
|
const dayKeys = getRuntimeStorageDayKeys(startTime, endTime);
|
|
274
|
-
const
|
|
275
|
-
|
|
276
|
-
(
|
|
277
|
-
|
|
274
|
+
const [bucketTradeGroups, legacyKeys] = await Promise.all([
|
|
275
|
+
Promise.all(
|
|
276
|
+
dayKeys.map(
|
|
277
|
+
(dayKey) => getHashJsonValues(
|
|
278
|
+
redisKeys2.runtimeTradeBucket(userName, dayKey)
|
|
279
|
+
)
|
|
278
280
|
)
|
|
279
|
-
)
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
281
|
+
),
|
|
282
|
+
getKeys(redisKeys2.runtimeTrades(userName))
|
|
283
|
+
]);
|
|
284
|
+
const legacyTradeKeys = legacyKeys.filter(
|
|
285
|
+
(key) => !key.startsWith(redisKeys2.runtimeTradeBuckets(userName))
|
|
286
|
+
);
|
|
287
|
+
const legacyTrades = await Promise.all(
|
|
288
|
+
legacyTradeKeys.map((key) => getData2(key, null))
|
|
289
|
+
);
|
|
290
|
+
const dedupedTrades = /* @__PURE__ */ new Map();
|
|
291
|
+
for (const trade of [...legacyTrades, ...bucketTradeGroups.flat()]) {
|
|
283
292
|
if (!isRuntimeTradeRecord(trade)) {
|
|
284
293
|
continue;
|
|
285
294
|
}
|
|
286
|
-
|
|
295
|
+
const existing = dedupedTrades.get(trade.orderId);
|
|
296
|
+
if (!existing || (trade.lastSyncedAt ?? Number.NEGATIVE_INFINITY) >= (existing.lastSyncedAt ?? Number.NEGATIVE_INFINITY)) {
|
|
297
|
+
dedupedTrades.set(trade.orderId, trade);
|
|
298
|
+
}
|
|
287
299
|
}
|
|
288
|
-
|
|
289
|
-
|
|
300
|
+
return [...dedupedTrades.values()].filter(filterByWindow).sort((left, right) => left.entryTimestamp - right.entryTimestamp);
|
|
301
|
+
};
|
|
302
|
+
var getTradeStrategyRevision = (trade) => trade.strategyRevision ?? (trade.runtimeLineage?.schemaVersion === 3 ? trade.runtimeLineage.strategyRevision : void 0);
|
|
303
|
+
var buildStrategyRevisionChanges = (trades) => {
|
|
304
|
+
const changes = [];
|
|
305
|
+
let previousRevision;
|
|
306
|
+
for (const trade of [...trades].sort(
|
|
307
|
+
(left, right) => left.entryTimestamp - right.entryTimestamp || left.orderId.localeCompare(right.orderId)
|
|
308
|
+
)) {
|
|
309
|
+
const strategyRevision = getTradeStrategyRevision(trade);
|
|
310
|
+
if (!strategyRevision) continue;
|
|
311
|
+
if (previousRevision && strategyRevision !== previousRevision) {
|
|
312
|
+
changes.push({
|
|
313
|
+
timestamp: trade.entryTimestamp,
|
|
314
|
+
strategyRevision
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
previousRevision = strategyRevision;
|
|
290
318
|
}
|
|
291
|
-
|
|
292
|
-
const trades = await Promise.all(keys.map((key) => getData2(key, null)));
|
|
293
|
-
return trades.filter(isRuntimeTradeRecord).filter(filterByWindow).sort((left, right) => left.entryTimestamp - right.entryTimestamp);
|
|
319
|
+
return changes;
|
|
294
320
|
};
|
|
295
321
|
var buildExchangeTimeRanges = (startTime, endTime) => {
|
|
296
322
|
const ranges = [];
|
|
@@ -531,14 +557,6 @@ var loadRuntimeDashboard = async ({
|
|
|
531
557
|
)
|
|
532
558
|
)
|
|
533
559
|
);
|
|
534
|
-
const runtimeIdentityKey = (trade) => buildRuntimeStrategyIdentityKey({
|
|
535
|
-
strategyName: trade.strategy,
|
|
536
|
-
configId: trade.strategyRevision,
|
|
537
|
-
universe: trade.universe,
|
|
538
|
-
accountId: trade.accountId,
|
|
539
|
-
deploymentId: trade.deploymentId,
|
|
540
|
-
policyProfileId: trade.policyProfileId
|
|
541
|
-
});
|
|
542
560
|
const identityByKey = /* @__PURE__ */ new Map();
|
|
543
561
|
for (const deployment of runtimeDeployments) {
|
|
544
562
|
for (const resolvedStrategy of resolvedStrategiesByDeployment.get(
|
|
@@ -574,24 +592,12 @@ var loadRuntimeDashboard = async ({
|
|
|
574
592
|
});
|
|
575
593
|
}
|
|
576
594
|
}
|
|
577
|
-
const accountScopedTrades = allTrades;
|
|
578
|
-
for (const trade of accountScopedTrades) {
|
|
579
|
-
const key = runtimeIdentityKey(trade);
|
|
580
|
-
const configuredIdentity = identityByKey.get(key);
|
|
581
|
-
if (!configuredIdentity) continue;
|
|
582
|
-
const strategyRevision = trade.strategyRevision ?? (trade.runtimeLineage?.schemaVersion === 3 ? trade.runtimeLineage.strategyRevision : void 0);
|
|
583
|
-
if (strategyRevision !== configuredIdentity.strategyRevision) continue;
|
|
584
|
-
identityByKey.set(key, {
|
|
585
|
-
...configuredIdentity,
|
|
586
|
-
interval: String(
|
|
587
|
-
trade.interval ?? configuredIdentity.interval
|
|
588
|
-
)
|
|
589
|
-
});
|
|
590
|
-
}
|
|
591
595
|
const strategies = await Promise.all(
|
|
592
596
|
[...identityByKey.entries()].map(async ([runtimeKey, identity]) => {
|
|
593
597
|
const { strategyName } = identity;
|
|
594
|
-
const strategyTrades =
|
|
598
|
+
const strategyTrades = allTrades.filter(
|
|
599
|
+
(trade) => trade.strategy === strategyName && String(trade.interval) === String(identity.interval)
|
|
600
|
+
).sort((left, right) => right.entryTimestamp - left.entryTimestamp);
|
|
595
601
|
const orders = strategyTrades.sort((left, right) => {
|
|
596
602
|
const leftDate = left.exitTimestamp ?? left.entryTimestamp;
|
|
597
603
|
const rightDate = right.exitTimestamp ?? right.entryTimestamp;
|
|
@@ -623,6 +629,7 @@ var loadRuntimeDashboard = async ({
|
|
|
623
629
|
stat: analytics.stat,
|
|
624
630
|
summary: analytics.summary,
|
|
625
631
|
orderLog: analytics.orderLog,
|
|
632
|
+
revisionChanges: buildStrategyRevisionChanges(strategyTrades),
|
|
626
633
|
recentTrades: strategyTrades.slice(0, 8).map((trade) => toRuntimeTradeView(trade, endTime)),
|
|
627
634
|
orders
|
|
628
635
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tradejs/node",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.19-beta.233",
|
|
4
4
|
"description": "Node-only runtime for the TradeJS TypeScript framework: strategies, backtests, Pine strategy loading, and plugin registries.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tradejs",
|
|
@@ -89,9 +89,9 @@
|
|
|
89
89
|
"dependencies": {
|
|
90
90
|
"@langchain/core": "^1.2.3",
|
|
91
91
|
"@langchain/openai": "^1.5.5",
|
|
92
|
-
"@tradejs/core": "^3.1.
|
|
93
|
-
"@tradejs/infra": "^3.1.
|
|
94
|
-
"@tradejs/types": "^3.1.
|
|
92
|
+
"@tradejs/core": "^3.1.19-beta.233",
|
|
93
|
+
"@tradejs/infra": "^3.1.19-beta.233",
|
|
94
|
+
"@tradejs/types": "^3.1.19-beta.233",
|
|
95
95
|
"@types/node": "^24",
|
|
96
96
|
"chalk": "4.1.2",
|
|
97
97
|
"ioredis": "5.11.1",
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
"typescript": "^5.9"
|
|
105
105
|
},
|
|
106
106
|
"devDependencies": {
|
|
107
|
-
"@tradejs/indicators": "^3.1.
|
|
107
|
+
"@tradejs/indicators": "^3.1.19-beta.233",
|
|
108
108
|
"@tradejs/strategy-adaptive-momentum-ribbon": "3.0.2",
|
|
109
109
|
"@tradejs/strategy-hyperliquid-consensus": "3.0.2",
|
|
110
110
|
"@tradejs/strategy-kit": "3.0.3",
|