@tradejs/node 3.1.11 → 3.1.12-beta.217

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,345 +0,0 @@
1
- import {
2
- getStrategyCreator,
3
- getStrategyPluginSource
4
- } from "./chunk-C3KRBNUR.mjs";
5
- import {
6
- loadTradejsConfig
7
- } from "./chunk-LZDXRXIU.mjs";
8
-
9
- // src/runtimeStrategies.ts
10
- import { readFile } from "fs/promises";
11
- import path from "path";
12
- import { getRuntimeControls } from "@tradejs/infra/runtimeControls";
13
- import { resolveTradingAccount } from "@tradejs/infra/tradingAccounts";
14
- var INTERVALS = /* @__PURE__ */ new Set([
15
- "1",
16
- "3",
17
- "5",
18
- "15",
19
- "30",
20
- "60",
21
- "120",
22
- "240",
23
- "360",
24
- "720",
25
- "D",
26
- "W",
27
- "M"
28
- ]);
29
- var RUNTIME_KEYS = /* @__PURE__ */ new Set(["deployments"]);
30
- var DEPLOYMENT_KEYS = /* @__PURE__ */ new Set([
31
- "label",
32
- "connectorName",
33
- "provider",
34
- "accountId",
35
- "enabled",
36
- "strategies",
37
- "assetClasses",
38
- "tickers"
39
- ]);
40
- var STRATEGY_KEYS = /* @__PURE__ */ new Set(["version", "enabled", "selection", "config"]);
41
- var SELECTION_KEYS = /* @__PURE__ */ new Set(["tickers"]);
42
- var FORBIDDEN_CONFIG_KEYS = /* @__PURE__ */ new Set([
43
- "ACCOUNT_ID",
44
- "DEPLOYMENT_ID",
45
- "CONNECTOR_NAME",
46
- "ENABLE"
47
- ]);
48
- var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
49
- var readPackageManifest = async (projectRoot) => {
50
- const candidates = [
51
- process.env.TRADEJS_RUNTIME_PACKAGE_MANIFEST,
52
- path.join(projectRoot, "runtime-package-manifest.json"),
53
- "/app/runtime-package-manifest.json"
54
- ].filter((candidate) => Boolean(candidate));
55
- for (const candidate of candidates) {
56
- try {
57
- return JSON.parse(
58
- await readFile(candidate, "utf8")
59
- );
60
- } catch {
61
- }
62
- }
63
- return { packages: {} };
64
- };
65
- var resolveInstalledPackageVersion = async (projectRoot, packageName, manifest) => {
66
- if (!packageName || packageName === "runtime") return null;
67
- const manifestVersion = manifest.packages?.[packageName];
68
- if (manifestVersion) return manifestVersion;
69
- try {
70
- const packageJsonPath = path.join(
71
- projectRoot,
72
- "node_modules",
73
- ...packageName.split("/"),
74
- "package.json"
75
- );
76
- const packageJson = JSON.parse(await readFile(packageJsonPath, "utf8"));
77
- return packageJson.version ?? null;
78
- } catch {
79
- return null;
80
- }
81
- };
82
- var resolveStrategyPackageName = async ({
83
- pluginSource,
84
- projectRoot
85
- }) => {
86
- if (!pluginSource) return null;
87
- if (!pluginSource.startsWith(".") && !path.isAbsolute(pluginSource)) {
88
- return pluginSource;
89
- }
90
- try {
91
- const packageJson = JSON.parse(
92
- await readFile(path.join(projectRoot, "package.json"), "utf8")
93
- );
94
- return typeof packageJson.name === "string" && packageJson.name.trim() ? packageJson.name : null;
95
- } catch {
96
- return null;
97
- }
98
- };
99
- var verifyStringArray = (value) => value === void 0 || Array.isArray(value) && value.every((item) => typeof item === "string");
100
- var verifyStrategySelection = (value) => value === void 0 || isRecord(value) && Object.keys(value).length === 1 && Object.keys(value).every((key) => SELECTION_KEYS.has(key)) && Array.isArray(value.tickers) && value.tickers.length > 0 && value.tickers.every(
101
- (ticker) => typeof ticker === "string" && ticker.trim().length > 0
102
- );
103
- var cloneSelection = (selection) => selection ? { tickers: [...selection.tickers] } : void 0;
104
- var resolveStrategySelection = ({
105
- deployment,
106
- strategy
107
- }) => cloneSelection(
108
- strategy.selection ?? (deployment.tickers ? { tickers: deployment.tickers } : void 0)
109
- );
110
- var verifyDeploymentDeclaration = (deploymentId, value) => {
111
- if (!deploymentId.trim() || !isRecord(value) || Object.keys(value).some((key) => !DEPLOYMENT_KEYS.has(key)) || typeof value.connectorName !== "string" || !value.connectorName.trim() || typeof value.accountId !== "string" || !value.accountId.trim() || value.label !== void 0 && typeof value.label !== "string" || value.provider !== void 0 && typeof value.provider !== "string" || value.enabled !== void 0 && typeof value.enabled !== "boolean" || !verifyStringArray(value.assetClasses) || !verifyStringArray(value.tickers) || !isRecord(value.strategies) || !Object.keys(value.strategies).length) {
112
- throw new Error(`Invalid runtime deployment declaration: ${deploymentId}`);
113
- }
114
- for (const [strategyName, strategyValue] of Object.entries(
115
- value.strategies
116
- )) {
117
- if (!strategyName.trim() || !isRecord(strategyValue) || Object.keys(strategyValue).some((key) => !STRATEGY_KEYS.has(key)) || !Number.isSafeInteger(strategyValue.version) || Number(strategyValue.version) <= 0 || typeof strategyValue.enabled !== "boolean" || !verifyStrategySelection(strategyValue.selection) || !isRecord(strategyValue.config) || Object.keys(strategyValue.config).some(
118
- (key) => FORBIDDEN_CONFIG_KEYS.has(key)
119
- ) || !INTERVALS.has(String(strategyValue.config.INTERVAL)) || !["crypto", "tradfi"].includes(String(strategyValue.config.UNIVERSE))) {
120
- throw new Error(
121
- `Invalid runtime strategy declaration: ${deploymentId}/${strategyName}`
122
- );
123
- }
124
- }
125
- return value;
126
- };
127
- var verifyRuntimeDeclaration = (value) => {
128
- if (!isRecord(value) || Object.keys(value).some((key) => !RUNTIME_KEYS.has(key)) || !isRecord(value.deployments) || !Object.keys(value.deployments).length) {
129
- throw new Error("Invalid runtime declaration");
130
- }
131
- for (const [deploymentId, deployment] of Object.entries(value.deployments)) {
132
- verifyDeploymentDeclaration(deploymentId, deployment);
133
- }
134
- return value;
135
- };
136
- var toRuntimeDeployment = ({
137
- id,
138
- declaration,
139
- controls
140
- }) => {
141
- const deploymentEnabled = declaration.enabled ?? true;
142
- return {
143
- id,
144
- label: declaration.label?.trim() || id,
145
- connectorName: declaration.connectorName.trim(),
146
- provider: (declaration.provider || declaration.connectorName).trim().toLowerCase(),
147
- accountId: declaration.accountId.trim(),
148
- enabled: deploymentEnabled,
149
- strategies: Object.entries(declaration.strategies).map(
150
- ([strategyName, strategy]) => {
151
- const selection = resolveStrategySelection({
152
- deployment: declaration,
153
- strategy
154
- });
155
- return {
156
- strategyName,
157
- version: strategy.version,
158
- enabled: strategy.enabled,
159
- controlState: deploymentEnabled && strategy.enabled && !controls.deployments[id]?.[strategyName]?.entriesPaused ? "active" : "entries_paused",
160
- ...selection ? { selection } : {}
161
- };
162
- }
163
- ),
164
- ...declaration.assetClasses ? { assetClasses: declaration.assetClasses } : {},
165
- ...declaration.tickers ? { tickers: declaration.tickers } : {}
166
- };
167
- };
168
- var loadRuntimeDeclaration = async (projectRoot) => {
169
- const projectConfig = await loadTradejsConfig(projectRoot);
170
- if (!projectConfig.runtime) {
171
- throw new Error("Runtime declaration is required in tradejs.config.ts");
172
- }
173
- return verifyRuntimeDeclaration(projectConfig.runtime);
174
- };
175
- var listRuntimeDeployments = async ({
176
- userName,
177
- projectRoot
178
- }) => {
179
- const [runtime, controls] = await Promise.all([
180
- loadRuntimeDeclaration(projectRoot),
181
- getRuntimeControls(userName)
182
- ]);
183
- return Object.entries(runtime.deployments).map(
184
- ([id, declaration]) => toRuntimeDeployment({ id, declaration, controls })
185
- ).sort((left, right) => left.label.localeCompare(right.label));
186
- };
187
- var getRuntimeDeployment = async ({
188
- userName,
189
- projectRoot,
190
- deploymentId
191
- }) => {
192
- const deployments = await listRuntimeDeployments({ userName, projectRoot });
193
- return deployments.find((deployment) => deployment.id === deploymentId) ?? null;
194
- };
195
- var resolveAccountId = async ({
196
- userName,
197
- deployment,
198
- universe
199
- }) => {
200
- const account = await resolveTradingAccount({
201
- userName,
202
- accountId: deployment.accountId,
203
- provider: deployment.provider,
204
- universe
205
- });
206
- if (!account) {
207
- throw new Error(`Trading account not found: ${deployment.accountId}`);
208
- }
209
- return account.id;
210
- };
211
- var loadResolvedRuntimeStrategies = async ({
212
- userName,
213
- projectRoot,
214
- deploymentId,
215
- universe,
216
- accountId,
217
- interval
218
- }) => {
219
- const [runtime, controls, packageManifest] = await Promise.all([
220
- loadRuntimeDeclaration(projectRoot),
221
- getRuntimeControls(userName),
222
- readPackageManifest(projectRoot)
223
- ]);
224
- const declaration = runtime.deployments[deploymentId];
225
- if (!declaration) {
226
- throw new Error(`Runtime deployment not found: ${deploymentId}`);
227
- }
228
- const deployment = toRuntimeDeployment({
229
- id: deploymentId,
230
- declaration,
231
- controls
232
- });
233
- const strategies = await Promise.all(
234
- Object.entries(declaration.strategies).map(
235
- async ([strategyName, strategyDeclaration]) => {
236
- const strategyCreator = await getStrategyCreator(
237
- strategyName,
238
- projectRoot
239
- );
240
- if (!strategyCreator) {
241
- throw new Error(`Unknown strategy: ${strategyName}`);
242
- }
243
- const pluginSource = await getStrategyPluginSource(strategyName, projectRoot) ?? null;
244
- const strategyPackage = await resolveStrategyPackageName({
245
- pluginSource,
246
- projectRoot
247
- });
248
- const [strategyPackageVersion, runtimePackageVersion] = await Promise.all([
249
- resolveInstalledPackageVersion(
250
- projectRoot,
251
- strategyPackage,
252
- packageManifest
253
- ),
254
- resolveInstalledPackageVersion(
255
- projectRoot,
256
- "@tradejs/node",
257
- packageManifest
258
- )
259
- ]);
260
- if (!strategyPackage || !strategyPackageVersion) {
261
- throw new Error(
262
- `Installed strategy package not found: ${strategyName}`
263
- );
264
- }
265
- if (!runtimePackageVersion) {
266
- throw new Error("Installed @tradejs/node package version not found");
267
- }
268
- const strategyView = deployment.strategies.find(
269
- (candidate) => candidate.strategyName === strategyName
270
- );
271
- const selection = resolveStrategySelection({
272
- deployment: declaration,
273
- strategy: strategyDeclaration
274
- });
275
- const strategyConfig = strategyDeclaration.config;
276
- const strategyUniverse = strategyConfig.UNIVERSE;
277
- const resolvedAccountId = await resolveAccountId({
278
- userName,
279
- deployment,
280
- universe: strategyUniverse
281
- });
282
- return {
283
- strategyName,
284
- version: strategyDeclaration.version,
285
- enabled: strategyDeclaration.enabled,
286
- controlState: strategyView?.controlState ?? "entries_paused",
287
- interval: String(strategyConfig.INTERVAL),
288
- universe: strategyUniverse,
289
- accountId: resolvedAccountId,
290
- strategyPackage,
291
- strategyPackageVersion,
292
- runtimePackageVersion,
293
- strategyCreator,
294
- sourceStrategyConfig: strategyConfig,
295
- strategyConfig,
296
- ...selection ? { selection } : {}
297
- };
298
- }
299
- )
300
- );
301
- const filtered = strategies.filter(
302
- (candidate) => (!universe || candidate.universe === universe) && (!interval || String(candidate.interval) === String(interval)) && (!accountId || candidate.accountId === accountId)
303
- );
304
- const identities = /* @__PURE__ */ new Set();
305
- for (const candidate of filtered) {
306
- const identity = `${candidate.strategyName}:${candidate.accountId ?? "default"}`;
307
- if (identities.has(identity)) {
308
- throw new Error(`Runtime strategy conflict: ${identity}`);
309
- }
310
- identities.add(identity);
311
- }
312
- return filtered;
313
- };
314
- var getRuntimeStrategyPackageMetadata = async ({
315
- strategyName,
316
- projectRoot
317
- }) => {
318
- const packageManifest = await readPackageManifest(projectRoot);
319
- const pluginSource = await getStrategyPluginSource(strategyName, projectRoot) ?? null;
320
- const strategyPackage = await resolveStrategyPackageName({
321
- pluginSource,
322
- projectRoot
323
- });
324
- return {
325
- strategyPackage,
326
- strategyPackageVersion: await resolveInstalledPackageVersion(
327
- projectRoot,
328
- strategyPackage,
329
- packageManifest
330
- ),
331
- runtimePackageVersion: await resolveInstalledPackageVersion(
332
- projectRoot,
333
- "@tradejs/node",
334
- packageManifest
335
- )
336
- };
337
- };
338
-
339
- export {
340
- verifyRuntimeDeclaration,
341
- listRuntimeDeployments,
342
- getRuntimeDeployment,
343
- loadResolvedRuntimeStrategies,
344
- getRuntimeStrategyPackageMetadata
345
- };