@tradejs/node 3.1.8-beta.206 → 3.1.8-beta.210

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.
@@ -1,11 +1,16 @@
1
+ import {
2
+ listRuntimeDeployments,
3
+ loadResolvedRuntimeStrategies
4
+ } from "./chunk-F7ODY5W4.mjs";
1
5
  import {
2
6
  buildExchangeFallbackRuntimeTrades,
3
7
  takeClosedPnlMatch
4
8
  } from "./chunk-FB5NUEOQ.mjs";
5
9
  import {
6
10
  getConnectorCreatorByProvider
7
- } from "./chunk-3TWULKHV.mjs";
8
- import "./chunk-WS5DYEVZ.mjs";
11
+ } from "./chunk-QVKUROR2.mjs";
12
+ import "./chunk-MEZIXBZ3.mjs";
13
+ import "./chunk-LZDXRXIU.mjs";
9
14
  import "./chunk-Y6FXYEAI.mjs";
10
15
 
11
16
  // src/runtimeDashboard.ts
@@ -15,8 +20,6 @@ import {
15
20
  listTradingAccounts,
16
21
  resolveTradingAccount
17
22
  } from "@tradejs/infra/tradingAccounts";
18
- import { listRuntimeDeployments } from "@tradejs/infra/runtimeDeployments";
19
- import { getRuntimeStrategyRelease } from "@tradejs/infra/runtimeStrategyReleases";
20
23
  import {
21
24
  getData as getData2,
22
25
  getHashJsonValues,
@@ -31,214 +34,6 @@ import {
31
34
  buildRuntimeStrategyIdentityKey
32
35
  } from "@tradejs/core/runtimeTrades";
33
36
 
34
- // src/strategyEvidenceTimeline.ts
35
- import fs from "fs/promises";
36
- import path from "path";
37
- import {
38
- canonicalStrategyEvidenceJson,
39
- safeStrategyEvidenceSegment,
40
- verifyStrategyEvidenceMarkerEnvelope
41
- } from "@tradejs/infra/strategyReleaseEvidence";
42
- var DEFAULT_MARKER_DIRECTORY = "data/strategy-release/markers";
43
- var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
44
- var isNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
45
- var strategyEvidenceTimelineSelectorKey = (selector) => [
46
- selector.strategy,
47
- selector.releaseVersion ?? "",
48
- selector.compositionId ?? "",
49
- selector.gitSha ?? "",
50
- selector.gateFingerprint ?? "",
51
- selector.configFingerprint ?? "",
52
- selector.contextFingerprint ?? "",
53
- selector.requireCompleteLineage ? "exact" : "partial"
54
- ].join(":");
55
- var discoverJsonFiles = async (rootDir) => {
56
- const files = [];
57
- const visit = async (directory, depth) => {
58
- if (depth > 12) return;
59
- let entries;
60
- try {
61
- entries = await fs.readdir(directory, { withFileTypes: true });
62
- } catch (error) {
63
- if (error.code === "ENOENT") return;
64
- throw error;
65
- }
66
- await Promise.all(
67
- entries.map(async (entry) => {
68
- if (entry.name.startsWith(".") || entry.name.includes(".tmp-")) return;
69
- const entryPath = path.join(directory, entry.name);
70
- if (entry.isDirectory()) {
71
- await visit(entryPath, depth + 1);
72
- } else if (entry.isFile() && entry.name.endsWith(".json")) {
73
- files.push(entryPath);
74
- }
75
- })
76
- );
77
- };
78
- await visit(rootDir, 0);
79
- return files.sort();
80
- };
81
- var inferMatchingStrategies = ({
82
- filePath,
83
- rootDir,
84
- parsed,
85
- strategies
86
- }) => {
87
- const payload = asRecord(asRecord(parsed)?.payload);
88
- const declaredStrategy = isNonEmptyString(payload?.strategy) ? payload.strategy : null;
89
- const directoryStrategy = path.relative(rootDir, filePath).split(path.sep)[0];
90
- return strategies.filter(
91
- (strategy) => strategy === declaredStrategy || directoryStrategy === safeStrategyEvidenceSegment(strategy)
92
- );
93
- };
94
- var missingTimeline = () => ({
95
- status: "missing",
96
- observedFrom: null,
97
- markers: []
98
- });
99
- var notAttachedTimeline = () => ({
100
- status: "not_attached",
101
- observedFrom: null,
102
- markers: []
103
- });
104
- var invalidTimeline = () => ({
105
- status: "invalid",
106
- observedFrom: null,
107
- markers: []
108
- });
109
- var loadStrategyEvidenceTimelines = async ({
110
- projectRoot,
111
- markerDir,
112
- selectors: requestedSelectors,
113
- startTime,
114
- endTime
115
- }) => {
116
- const selectors = [...requestedSelectors].filter((selector) => selector.strategy.trim().length > 0).sort(
117
- (left, right) => strategyEvidenceTimelineSelectorKey(left).localeCompare(
118
- strategyEvidenceTimelineSelectorKey(right)
119
- )
120
- );
121
- const strategies = [...new Set(selectors.map(({ strategy }) => strategy))];
122
- const timelines = new Map(
123
- selectors.map((selector) => [
124
- strategyEvidenceTimelineSelectorKey(selector),
125
- selector.releaseVersion ? notAttachedTimeline() : missingTimeline()
126
- ])
127
- );
128
- if (!selectors.length) return timelines;
129
- const configuredDir = markerDir?.trim() || DEFAULT_MARKER_DIRECTORY;
130
- const rootDir = path.isAbsolute(configuredDir) ? configuredDir : path.resolve(projectRoot, configuredDir);
131
- let files;
132
- try {
133
- files = await discoverJsonFiles(rootDir);
134
- } catch {
135
- for (const selector of selectors) {
136
- timelines.set(
137
- strategyEvidenceTimelineSelectorKey(selector),
138
- invalidTimeline()
139
- );
140
- }
141
- return timelines;
142
- }
143
- const envelopesByStrategy = /* @__PURE__ */ new Map();
144
- const invalidStrategies = /* @__PURE__ */ new Set();
145
- for (const filePath of files) {
146
- let parsed = null;
147
- try {
148
- parsed = JSON.parse(await fs.readFile(filePath, "utf8"));
149
- } catch {
150
- for (const strategy of inferMatchingStrategies({
151
- filePath,
152
- rootDir,
153
- parsed,
154
- strategies
155
- })) {
156
- invalidStrategies.add(strategy);
157
- }
158
- continue;
159
- }
160
- const matchingStrategies = inferMatchingStrategies({
161
- filePath,
162
- rootDir,
163
- parsed,
164
- strategies
165
- });
166
- if (!matchingStrategies.length) continue;
167
- try {
168
- const envelope = verifyStrategyEvidenceMarkerEnvelope(parsed);
169
- for (const strategy of matchingStrategies) {
170
- if (strategy !== envelope.payload.strategy) {
171
- invalidStrategies.add(strategy);
172
- }
173
- }
174
- if (!strategies.includes(envelope.payload.strategy)) {
175
- continue;
176
- }
177
- const envelopes = envelopesByStrategy.get(envelope.payload.strategy) ?? [];
178
- envelopes.push(envelope);
179
- envelopesByStrategy.set(envelope.payload.strategy, envelopes);
180
- } catch {
181
- for (const strategy of matchingStrategies) {
182
- invalidStrategies.add(strategy);
183
- }
184
- }
185
- }
186
- for (const selector of selectors) {
187
- const strategy = selector.strategy;
188
- const selectorKey = strategyEvidenceTimelineSelectorKey(selector);
189
- if (invalidStrategies.has(strategy)) {
190
- timelines.set(selectorKey, invalidTimeline());
191
- continue;
192
- }
193
- const envelopes = envelopesByStrategy.get(strategy) ?? [];
194
- if (!envelopes.length) continue;
195
- const hasCompleteSelector = selector.releaseVersion != null || Boolean(selector.compositionId) && Boolean(selector.gitSha) && Boolean(selector.gateFingerprint) && Boolean(selector.configFingerprint) && Boolean(selector.contextFingerprint);
196
- if (selector.requireCompleteLineage && !hasCompleteSelector) continue;
197
- const markersById = /* @__PURE__ */ new Map();
198
- let hasConflict = false;
199
- for (const envelope of envelopes) {
200
- for (const marker of envelope.payload.markers) {
201
- const existing = markersById.get(marker.id);
202
- if (existing && canonicalStrategyEvidenceJson(existing) !== canonicalStrategyEvidenceJson(marker)) {
203
- hasConflict = true;
204
- break;
205
- }
206
- markersById.set(marker.id, marker);
207
- }
208
- if (hasConflict) break;
209
- }
210
- if (hasConflict) {
211
- timelines.set(selectorKey, invalidTimeline());
212
- continue;
213
- }
214
- const matchingMarkers = [...markersById.values()].filter(
215
- (marker) => (!selector.compositionId || marker.compositionId === selector.compositionId) && (!selector.releaseVersion || marker.releaseVersion === selector.releaseVersion) && (!selector.gitSha || marker.gitSha === selector.gitSha) && (!selector.gateFingerprint || marker.gateFingerprint === selector.gateFingerprint) && (!selector.configFingerprint || marker.configFingerprint === selector.configFingerprint) && (!selector.contextFingerprint || marker.contextFingerprint === selector.contextFingerprint) && marker.timestamp >= startTime && marker.timestamp < endTime
216
- ).sort(
217
- (left, right) => left.timestamp - right.timestamp || left.type.localeCompare(right.type) || left.id.localeCompare(right.id)
218
- );
219
- let lastLossValue;
220
- let hasLastLossValue = false;
221
- const markers = matchingMarkers.filter((marker) => {
222
- if (marker.type !== "L") return true;
223
- if (hasLastLossValue && marker.maxLossValue === lastLossValue) {
224
- return false;
225
- }
226
- hasLastLossValue = true;
227
- lastLossValue = marker.maxLossValue;
228
- return true;
229
- });
230
- if (!markers.length && (selector.compositionId || selector.releaseVersion || selector.gitSha || selector.gateFingerprint || selector.configFingerprint || selector.contextFingerprint)) {
231
- continue;
232
- }
233
- timelines.set(selectorKey, {
234
- status: "verified",
235
- observedFrom: markers.length ? Math.min(...markers.map((marker) => marker.timestamp)) : Math.min(...envelopes.map((envelope) => envelope.payload.createdAt)),
236
- markers
237
- });
238
- }
239
- return timelines;
240
- };
241
-
242
37
  // src/runtimeTradeSync.ts
243
38
  import { TTL_1M } from "@tradejs/core/constants";
244
39
  import { getRuntimeStorageDayKey } from "@tradejs/core/time";
@@ -676,7 +471,7 @@ var loadRuntimeDashboard = async ({
676
471
  errors: exchangeErrors
677
472
  }),
678
473
  loadOpenPositions(connector, exchangeErrors),
679
- listRuntimeDeployments(userName),
474
+ listRuntimeDeployments({ userName, projectRoot }),
680
475
  listTradingAccounts(userName)
681
476
  ]);
682
477
  const relevantTrades = selectTradesForWindow(
@@ -721,9 +516,23 @@ var loadRuntimeDashboard = async ({
721
516
  const accountsById = new Map(
722
517
  tradingAccounts.map((account) => [account.id, account])
723
518
  );
519
+ const resolvedStrategiesByDeployment = new Map(
520
+ await Promise.all(
521
+ runtimeDeployments.map(
522
+ async (deployment) => [
523
+ deployment.id,
524
+ await loadResolvedRuntimeStrategies({
525
+ userName,
526
+ projectRoot,
527
+ deploymentId: deployment.id
528
+ })
529
+ ]
530
+ )
531
+ )
532
+ );
724
533
  const runtimeIdentityKey = (trade) => buildRuntimeStrategyIdentityKey({
725
534
  strategyName: trade.strategy,
726
- configId: trade.runtimeReleaseVersion ? `v${trade.runtimeReleaseVersion}` : void 0,
535
+ configId: trade.runtimeVersion ? `v${trade.runtimeVersion}` : void 0,
727
536
  universe: trade.universe,
728
537
  accountId: trade.accountId,
729
538
  deploymentId: trade.deploymentId,
@@ -731,42 +540,34 @@ var loadRuntimeDashboard = async ({
731
540
  });
732
541
  const identityByKey = /* @__PURE__ */ new Map();
733
542
  for (const deployment of runtimeDeployments) {
734
- for (const deploymentStrategy of deployment.strategies) {
735
- const release = await getRuntimeStrategyRelease(
736
- userName,
737
- deploymentStrategy.strategyName,
738
- deploymentStrategy.releaseVersion
739
- );
740
- if (!release) {
741
- throw new Error(
742
- `Runtime release not found: ${deploymentStrategy.strategyName} v${deploymentStrategy.releaseVersion}`
743
- );
744
- }
745
- const releaseUniverse = release.config.UNIVERSE === "tradfi" ? "tradfi" : "crypto";
746
- const releaseInterval = String(release.config.INTERVAL);
747
- const releaseConfigId = `v${deploymentStrategy.releaseVersion}`;
748
- const releasePolicyProfileId = typeof release.config.POLICY_PROFILE_ID === "string" ? release.config.POLICY_PROFILE_ID : void 0;
543
+ for (const resolvedStrategy of resolvedStrategiesByDeployment.get(
544
+ deployment.id
545
+ ) ?? []) {
546
+ const strategyUniverse = resolvedStrategy.universe;
547
+ const strategyInterval = resolvedStrategy.interval;
548
+ const strategyConfigId = `v${resolvedStrategy.version}`;
549
+ const strategyPolicyProfileId = typeof resolvedStrategy.strategyConfig.POLICY_PROFILE_ID === "string" ? resolvedStrategy.strategyConfig.POLICY_PROFILE_ID : void 0;
749
550
  const runtimeKey = buildRuntimeStrategyIdentityKey({
750
- strategyName: deploymentStrategy.strategyName,
751
- configId: releaseConfigId,
752
- universe: releaseUniverse,
551
+ strategyName: resolvedStrategy.strategyName,
552
+ configId: strategyConfigId,
553
+ universe: strategyUniverse,
753
554
  accountId: deployment.accountId,
754
555
  deploymentId: deployment.id,
755
- policyProfileId: releasePolicyProfileId
556
+ policyProfileId: strategyPolicyProfileId
756
557
  });
757
558
  identityByKey.set(runtimeKey, {
758
- strategyName: deploymentStrategy.strategyName,
759
- configId: releaseConfigId,
760
- releaseVersion: deploymentStrategy.releaseVersion,
761
- controlState: deploymentStrategy.controlState,
762
- interval: releaseInterval,
763
- universe: releaseUniverse,
559
+ strategyName: resolvedStrategy.strategyName,
560
+ configId: strategyConfigId,
561
+ version: resolvedStrategy.version,
562
+ controlState: resolvedStrategy.controlState,
563
+ interval: strategyInterval,
564
+ universe: strategyUniverse,
764
565
  accountId: deployment.accountId,
765
566
  accountLabel: accountsById.get(deployment.accountId)?.label,
766
567
  deploymentId: deployment.id,
767
- policyProfileId: releasePolicyProfileId,
768
- enabled: deployment.enabled && deploymentStrategy.controlState !== "entries_paused",
769
- config: release.config,
568
+ policyProfileId: strategyPolicyProfileId,
569
+ enabled: resolvedStrategy.controlState !== "entries_paused",
570
+ config: resolvedStrategy.strategyConfig,
770
571
  connected: deployment.enabled
771
572
  });
772
573
  }
@@ -776,8 +577,8 @@ var loadRuntimeDashboard = async ({
776
577
  const key = runtimeIdentityKey(trade);
777
578
  const configuredIdentity = identityByKey.get(key);
778
579
  if (!configuredIdentity) continue;
779
- const releaseVersion = trade.runtimeReleaseVersion ?? (trade.runtimeLineage?.schemaVersion === 2 ? trade.runtimeLineage.releaseVersion : void 0);
780
- if (releaseVersion !== configuredIdentity.releaseVersion) continue;
580
+ const version = trade.runtimeVersion ?? (trade.runtimeLineage?.schemaVersion === 2 ? trade.runtimeLineage.version : void 0);
581
+ if (version !== configuredIdentity.version) continue;
781
582
  identityByKey.set(key, {
782
583
  ...configuredIdentity,
783
584
  interval: String(
@@ -785,17 +586,6 @@ var loadRuntimeDashboard = async ({
785
586
  )
786
587
  });
787
588
  }
788
- const evidenceTimelines = await loadStrategyEvidenceTimelines({
789
- projectRoot,
790
- markerDir: process.env.STRATEGY_RELEASE_MARKER_DIR,
791
- selectors: [...identityByKey.values()].map((identity) => ({
792
- strategy: identity.strategyName,
793
- releaseVersion: identity.releaseVersion,
794
- requireCompleteLineage: true
795
- })),
796
- startTime,
797
- endTime
798
- });
799
589
  const strategies = await Promise.all(
800
590
  [...identityByKey.entries()].map(async ([runtimeKey, identity]) => {
801
591
  const { strategyName } = identity;
@@ -815,7 +605,7 @@ var loadRuntimeDashboard = async ({
815
605
  runtimeKey,
816
606
  strategyName,
817
607
  configId: identity.configId,
818
- releaseVersion: identity.releaseVersion,
608
+ version: identity.version,
819
609
  controlState: identity.controlState,
820
610
  interval: identity.interval,
821
611
  universe: identity.universe,
@@ -830,17 +620,6 @@ var loadRuntimeDashboard = async ({
830
620
  stat: analytics.stat,
831
621
  summary: analytics.summary,
832
622
  orderLog: analytics.orderLog,
833
- evidenceTimeline: evidenceTimelines.get(
834
- strategyEvidenceTimelineSelectorKey({
835
- strategy: strategyName,
836
- releaseVersion: identity.releaseVersion,
837
- requireCompleteLineage: true
838
- })
839
- ) ?? {
840
- status: "not_attached",
841
- observedFrom: null,
842
- markers: []
843
- },
844
623
  recentTrades: strategyTrades.slice(0, 8).map((trade) => toRuntimeTradeView(trade, endTime)),
845
624
  orders
846
625
  };
@@ -1,8 +1,9 @@
1
- import { RuntimeStrategyControlState, Interval, MarketUniverse, StrategyCreator, StrategyConfig, RuntimeDeployment } from '@tradejs/types';
1
+ import { RuntimeStrategyControlState, Interval, MarketUniverse, StrategyCreator, StrategyConfig, RuntimeDeployment, TradejsRuntimeDeclaration } from '@tradejs/types';
2
2
 
3
3
  interface ResolvedRuntimeStrategy {
4
4
  strategyName: string;
5
- releaseVersion: number;
5
+ version: number;
6
+ enabled: boolean;
6
7
  controlState: RuntimeStrategyControlState;
7
8
  interval: Interval;
8
9
  universe: MarketUniverse;
@@ -14,10 +15,20 @@ interface ResolvedRuntimeStrategy {
14
15
  sourceStrategyConfig: StrategyConfig;
15
16
  strategyConfig: StrategyConfig;
16
17
  }
17
- declare const loadResolvedRuntimeStrategies: ({ userName, projectRoot, deployment, universe, accountId, interval, }: {
18
+ declare const verifyRuntimeDeclaration: (value: unknown) => TradejsRuntimeDeclaration;
19
+ declare const listRuntimeDeployments: ({ userName, projectRoot, }: {
18
20
  userName: string;
19
21
  projectRoot: string;
20
- deployment?: RuntimeDeployment | null;
22
+ }) => Promise<RuntimeDeployment[]>;
23
+ declare const getRuntimeDeployment: ({ userName, projectRoot, deploymentId, }: {
24
+ userName: string;
25
+ projectRoot: string;
26
+ deploymentId: string;
27
+ }) => Promise<RuntimeDeployment | null>;
28
+ declare const loadResolvedRuntimeStrategies: ({ userName, projectRoot, deploymentId, universe, accountId, interval, }: {
29
+ userName: string;
30
+ projectRoot: string;
31
+ deploymentId: string;
21
32
  universe?: MarketUniverse;
22
33
  accountId?: string;
23
34
  interval?: Interval;
@@ -31,4 +42,4 @@ declare const getRuntimeStrategyPackageMetadata: ({ strategyName, projectRoot, }
31
42
  runtimePackageVersion: string | null;
32
43
  }>;
33
44
 
34
- export { type ResolvedRuntimeStrategy, getRuntimeStrategyPackageMetadata, loadResolvedRuntimeStrategies };
45
+ export { type ResolvedRuntimeStrategy, getRuntimeDeployment, getRuntimeStrategyPackageMetadata, listRuntimeDeployments, loadResolvedRuntimeStrategies, verifyRuntimeDeclaration };
@@ -1,8 +1,9 @@
1
- import { RuntimeStrategyControlState, Interval, MarketUniverse, StrategyCreator, StrategyConfig, RuntimeDeployment } from '@tradejs/types';
1
+ import { RuntimeStrategyControlState, Interval, MarketUniverse, StrategyCreator, StrategyConfig, RuntimeDeployment, TradejsRuntimeDeclaration } from '@tradejs/types';
2
2
 
3
3
  interface ResolvedRuntimeStrategy {
4
4
  strategyName: string;
5
- releaseVersion: number;
5
+ version: number;
6
+ enabled: boolean;
6
7
  controlState: RuntimeStrategyControlState;
7
8
  interval: Interval;
8
9
  universe: MarketUniverse;
@@ -14,10 +15,20 @@ interface ResolvedRuntimeStrategy {
14
15
  sourceStrategyConfig: StrategyConfig;
15
16
  strategyConfig: StrategyConfig;
16
17
  }
17
- declare const loadResolvedRuntimeStrategies: ({ userName, projectRoot, deployment, universe, accountId, interval, }: {
18
+ declare const verifyRuntimeDeclaration: (value: unknown) => TradejsRuntimeDeclaration;
19
+ declare const listRuntimeDeployments: ({ userName, projectRoot, }: {
18
20
  userName: string;
19
21
  projectRoot: string;
20
- deployment?: RuntimeDeployment | null;
22
+ }) => Promise<RuntimeDeployment[]>;
23
+ declare const getRuntimeDeployment: ({ userName, projectRoot, deploymentId, }: {
24
+ userName: string;
25
+ projectRoot: string;
26
+ deploymentId: string;
27
+ }) => Promise<RuntimeDeployment | null>;
28
+ declare const loadResolvedRuntimeStrategies: ({ userName, projectRoot, deploymentId, universe, accountId, interval, }: {
29
+ userName: string;
30
+ projectRoot: string;
31
+ deploymentId: string;
21
32
  universe?: MarketUniverse;
22
33
  accountId?: string;
23
34
  interval?: Interval;
@@ -31,4 +42,4 @@ declare const getRuntimeStrategyPackageMetadata: ({ strategyName, projectRoot, }
31
42
  runtimePackageVersion: string | null;
32
43
  }>;
33
44
 
34
- export { type ResolvedRuntimeStrategy, getRuntimeStrategyPackageMetadata, loadResolvedRuntimeStrategies };
45
+ export { type ResolvedRuntimeStrategy, getRuntimeDeployment, getRuntimeStrategyPackageMetadata, listRuntimeDeployments, loadResolvedRuntimeStrategies, verifyRuntimeDeclaration };