@tradejs/node 1.0.2 → 1.0.4
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/{ai-NNJ3RLLL.mjs → ai-G7ATN4YL.mjs} +3 -3
- package/dist/backtest.d.mts +1 -1
- package/dist/backtest.d.ts +1 -1
- package/dist/backtest.js +253 -137
- package/dist/backtest.mjs +52 -25
- package/dist/{chunk-OB4CSYDJ.mjs → chunk-7ICOZAKA.mjs} +0 -4
- package/dist/chunk-CIY64D57.mjs +271 -0
- package/dist/{chunk-ZIMX3JX2.mjs → chunk-LMAKIC3C.mjs} +1 -1
- package/dist/{chunk-DE7ADBIR.mjs → chunk-P2ZUWONT.mjs} +30 -2
- package/dist/{chunk-PXJJPAQT.mjs → chunk-RBE4PZER.mjs} +1 -1
- package/dist/chunk-ZY6ULOWK.mjs +246 -0
- package/dist/cli.js +140 -102
- package/dist/cli.mjs +26 -18
- package/dist/connectors.d.mts +9 -9
- package/dist/connectors.d.ts +9 -9
- package/dist/connectors.js +144 -74
- package/dist/connectors.mjs +2 -2
- package/dist/pine.d.mts +0 -1
- package/dist/pine.d.ts +0 -1
- package/dist/pine.js +0 -4
- package/dist/pine.mjs +1 -1
- package/dist/registry.d.mts +10 -10
- package/dist/registry.d.ts +10 -10
- package/dist/registry.js +156 -85
- package/dist/registry.mjs +2 -2
- package/dist/strategies.js +452 -166
- package/dist/strategies.mjs +300 -85
- package/package.json +6 -5
- package/dist/chunk-E2QNOA5M.mjs +0 -227
- package/dist/chunk-MHCXPD2B.mjs +0 -201
package/dist/registry.js
CHANGED
|
@@ -65,6 +65,7 @@ var TS_MODULE_RE = /\.(cts|mts|ts)$/i;
|
|
|
65
65
|
var cachedByCwd = /* @__PURE__ */ new Map();
|
|
66
66
|
var announcedConfigFile = /* @__PURE__ */ new Set();
|
|
67
67
|
var tsNodeRegistered = false;
|
|
68
|
+
var tsconfigPathsRegisteredByCwd = /* @__PURE__ */ new Set();
|
|
68
69
|
var getTradejsProjectCwd = (cwd) => {
|
|
69
70
|
const explicit = String(cwd ?? "").trim();
|
|
70
71
|
if (explicit) {
|
|
@@ -106,6 +107,28 @@ var ensureTsNodeRegistered = async () => {
|
|
|
106
107
|
});
|
|
107
108
|
tsNodeRegistered = true;
|
|
108
109
|
};
|
|
110
|
+
var ensureTsconfigPathsRegistered = async (cwd = getTradejsProjectCwd()) => {
|
|
111
|
+
const projectRoot = getTradejsProjectCwd(cwd);
|
|
112
|
+
if (tsconfigPathsRegisteredByCwd.has(projectRoot)) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const tsconfigPathsModule = await import("tsconfig-paths");
|
|
116
|
+
const loadConfig = tsconfigPathsModule.loadConfig;
|
|
117
|
+
const register = tsconfigPathsModule.register;
|
|
118
|
+
if (typeof loadConfig !== "function" || typeof register !== "function") {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const loadedConfig = loadConfig(projectRoot);
|
|
122
|
+
if (loadedConfig.resultType !== "success") {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
register({
|
|
126
|
+
baseUrl: loadedConfig.absoluteBaseUrl,
|
|
127
|
+
paths: loadedConfig.paths,
|
|
128
|
+
addMatchAll: false
|
|
129
|
+
});
|
|
130
|
+
tsconfigPathsRegisteredByCwd.add(projectRoot);
|
|
131
|
+
};
|
|
109
132
|
var toImportSpecifier = (moduleName) => {
|
|
110
133
|
if (moduleName.startsWith("file://")) {
|
|
111
134
|
return moduleName;
|
|
@@ -133,6 +156,7 @@ var importConfigFile = async (configFilePath) => {
|
|
|
133
156
|
if (ext === ".ts" || ext === ".mts") {
|
|
134
157
|
const requireFn = getRequireFn(import_path.default.dirname(configFilePath));
|
|
135
158
|
await ensureTsNodeRegistered();
|
|
159
|
+
await ensureTsconfigPathsRegistered(import_path.default.dirname(configFilePath));
|
|
136
160
|
return requireFn(configFilePath);
|
|
137
161
|
}
|
|
138
162
|
return import(
|
|
@@ -140,7 +164,7 @@ var importConfigFile = async (configFilePath) => {
|
|
|
140
164
|
configFileUrl
|
|
141
165
|
);
|
|
142
166
|
};
|
|
143
|
-
var importTradejsModule = async (moduleName) => {
|
|
167
|
+
var importTradejsModule = async (moduleName, cwd = getTradejsProjectCwd()) => {
|
|
144
168
|
const normalized = String(moduleName ?? "").trim();
|
|
145
169
|
if (!normalized) {
|
|
146
170
|
return {};
|
|
@@ -154,13 +178,15 @@ var importTradejsModule = async (moduleName) => {
|
|
|
154
178
|
}
|
|
155
179
|
}
|
|
156
180
|
const requireFn = getRequireFn(
|
|
157
|
-
import_path.default.isAbsolute(modulePath) ? import_path.default.dirname(modulePath) :
|
|
181
|
+
import_path.default.isAbsolute(modulePath) ? import_path.default.dirname(modulePath) : cwd
|
|
158
182
|
);
|
|
159
183
|
if (isTsModulePath(modulePath)) {
|
|
160
184
|
await ensureTsNodeRegistered();
|
|
185
|
+
await ensureTsconfigPathsRegistered(cwd);
|
|
161
186
|
return requireFn(modulePath);
|
|
162
187
|
}
|
|
163
188
|
if (isBareModuleSpecifier(normalized)) {
|
|
189
|
+
await ensureTsconfigPathsRegistered(cwd);
|
|
164
190
|
return requireFn(normalized);
|
|
165
191
|
}
|
|
166
192
|
try {
|
|
@@ -171,6 +197,7 @@ var importTradejsModule = async (moduleName) => {
|
|
|
171
197
|
} catch (error) {
|
|
172
198
|
if (isTsModulePath(modulePath)) {
|
|
173
199
|
await ensureTsNodeRegistered();
|
|
200
|
+
await ensureTsconfigPathsRegistered(cwd);
|
|
174
201
|
return requireFn(modulePath);
|
|
175
202
|
}
|
|
176
203
|
throw error;
|
|
@@ -248,14 +275,29 @@ var loadTradejsConfig = async (cwd = getTradejsProjectCwd()) => {
|
|
|
248
275
|
};
|
|
249
276
|
|
|
250
277
|
// src/strategy/manifests.ts
|
|
251
|
-
var
|
|
252
|
-
|
|
253
|
-
|
|
278
|
+
var createStrategyRegistryState = () => ({
|
|
279
|
+
strategyCreators: /* @__PURE__ */ new Map(),
|
|
280
|
+
strategyManifestsMap: /* @__PURE__ */ new Map(),
|
|
281
|
+
pluginsLoadPromise: null
|
|
282
|
+
});
|
|
283
|
+
var registryStateByProjectRoot = /* @__PURE__ */ new Map();
|
|
284
|
+
var getStrategyRegistryState = (cwd = getTradejsProjectCwd()) => {
|
|
285
|
+
const projectRoot = getTradejsProjectCwd(cwd);
|
|
286
|
+
let state = registryStateByProjectRoot.get(projectRoot);
|
|
287
|
+
if (!state) {
|
|
288
|
+
state = createStrategyRegistryState();
|
|
289
|
+
registryStateByProjectRoot.set(projectRoot, state);
|
|
290
|
+
}
|
|
291
|
+
return {
|
|
292
|
+
projectRoot,
|
|
293
|
+
state
|
|
294
|
+
};
|
|
295
|
+
};
|
|
254
296
|
var toUniqueModules = (modules = []) => [
|
|
255
297
|
...new Set(modules.map((moduleName) => moduleName.trim()).filter(Boolean))
|
|
256
298
|
];
|
|
257
|
-
var getConfiguredPluginModuleNames = async () => {
|
|
258
|
-
const config = await loadTradejsConfig();
|
|
299
|
+
var getConfiguredPluginModuleNames = async (cwd = getTradejsProjectCwd()) => {
|
|
300
|
+
const config = await loadTradejsConfig(cwd);
|
|
259
301
|
return {
|
|
260
302
|
strategyModules: toUniqueModules(config.strategies),
|
|
261
303
|
indicatorModules: toUniqueModules(config.indicators)
|
|
@@ -289,14 +331,14 @@ var extractIndicatorPluginDefinition = (moduleExport) => {
|
|
|
289
331
|
);
|
|
290
332
|
return indicatorEntries ? { indicatorEntries } : null;
|
|
291
333
|
};
|
|
292
|
-
var registerEntries = (entries, source) => {
|
|
334
|
+
var registerEntries = (entries, source, state) => {
|
|
293
335
|
for (const entry of entries) {
|
|
294
336
|
const strategyName = entry.manifest?.name;
|
|
295
337
|
if (!strategyName) {
|
|
296
338
|
import_logger2.logger.warn("Skip strategy entry without name from %s", source);
|
|
297
339
|
continue;
|
|
298
340
|
}
|
|
299
|
-
if (strategyCreators.has(strategyName)) {
|
|
341
|
+
if (state.strategyCreators.has(strategyName)) {
|
|
300
342
|
import_logger2.logger.warn(
|
|
301
343
|
'Skip duplicate strategy "%s" from %s: already registered',
|
|
302
344
|
strategyName,
|
|
@@ -304,106 +346,135 @@ var registerEntries = (entries, source) => {
|
|
|
304
346
|
);
|
|
305
347
|
continue;
|
|
306
348
|
}
|
|
307
|
-
strategyCreators.set(strategyName, entry.creator);
|
|
308
|
-
strategyManifestsMap.set(strategyName, entry.manifest);
|
|
349
|
+
state.strategyCreators.set(strategyName, entry.creator);
|
|
350
|
+
state.strategyManifestsMap.set(strategyName, entry.manifest);
|
|
309
351
|
}
|
|
310
352
|
};
|
|
311
|
-
var importStrategyPluginModule = async (moduleName) => {
|
|
353
|
+
var importStrategyPluginModule = async (moduleName, cwd = getTradejsProjectCwd()) => {
|
|
312
354
|
if (typeof importTradejsModule === "function") {
|
|
313
|
-
return importTradejsModule(moduleName);
|
|
355
|
+
return importTradejsModule(moduleName, cwd);
|
|
314
356
|
}
|
|
315
357
|
return import(
|
|
316
358
|
/* webpackIgnore: true */
|
|
317
359
|
moduleName
|
|
318
360
|
);
|
|
319
361
|
};
|
|
320
|
-
var ensureStrategyPluginsLoaded = async () => {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
362
|
+
var ensureStrategyPluginsLoaded = async (cwd = getTradejsProjectCwd()) => {
|
|
363
|
+
const { projectRoot, state } = getStrategyRegistryState(cwd);
|
|
364
|
+
if (!state.pluginsLoadPromise) {
|
|
365
|
+
(0, import_indicators.resetIndicatorRegistryCache)(projectRoot);
|
|
366
|
+
state.pluginsLoadPromise = (async () => {
|
|
367
|
+
const { strategyModules, indicatorModules } = await getConfiguredPluginModuleNames(projectRoot);
|
|
368
|
+
const strategySet = new Set(strategyModules);
|
|
369
|
+
const indicatorSet = new Set(indicatorModules);
|
|
370
|
+
const pluginModuleNames = [
|
|
371
|
+
.../* @__PURE__ */ new Set([...strategyModules, ...indicatorModules])
|
|
372
|
+
];
|
|
373
|
+
if (!pluginModuleNames.length) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
for (const moduleName of pluginModuleNames) {
|
|
377
|
+
try {
|
|
378
|
+
const resolvedModuleName = resolvePluginModuleSpecifier(
|
|
379
|
+
moduleName,
|
|
380
|
+
projectRoot
|
|
381
|
+
);
|
|
382
|
+
const moduleExport = await importStrategyPluginModule(
|
|
383
|
+
resolvedModuleName,
|
|
384
|
+
projectRoot
|
|
385
|
+
);
|
|
386
|
+
if (strategySet.has(moduleName)) {
|
|
387
|
+
const pluginDefinition = extractStrategyPluginDefinition(moduleExport);
|
|
388
|
+
if (!pluginDefinition) {
|
|
389
|
+
import_logger2.logger.warn(
|
|
390
|
+
'Skip strategy plugin "%s": export { strategyEntries } is missing',
|
|
391
|
+
moduleName
|
|
392
|
+
);
|
|
393
|
+
} else {
|
|
394
|
+
registerEntries(
|
|
395
|
+
pluginDefinition.strategyEntries,
|
|
396
|
+
moduleName,
|
|
397
|
+
state
|
|
398
|
+
);
|
|
399
|
+
}
|
|
345
400
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
401
|
+
if (indicatorSet.has(moduleName)) {
|
|
402
|
+
const indicatorPluginDefinition = extractIndicatorPluginDefinition(moduleExport);
|
|
403
|
+
if (!indicatorPluginDefinition) {
|
|
404
|
+
import_logger2.logger.warn(
|
|
405
|
+
'Skip indicator plugin "%s": export { indicatorEntries } is missing',
|
|
406
|
+
moduleName
|
|
407
|
+
);
|
|
408
|
+
} else {
|
|
409
|
+
(0, import_indicators.registerIndicatorEntries)(
|
|
410
|
+
indicatorPluginDefinition.indicatorEntries,
|
|
411
|
+
moduleName,
|
|
412
|
+
projectRoot
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
if (!strategySet.has(moduleName) && !indicatorSet.has(moduleName)) {
|
|
350
417
|
import_logger2.logger.warn(
|
|
351
|
-
'Skip
|
|
352
|
-
moduleName
|
|
353
|
-
);
|
|
354
|
-
} else {
|
|
355
|
-
(0, import_indicators.registerIndicatorEntries)(
|
|
356
|
-
indicatorPluginDefinition.indicatorEntries,
|
|
418
|
+
'Skip plugin "%s": no strategy/indicator sections requested in config',
|
|
357
419
|
moduleName
|
|
358
420
|
);
|
|
359
421
|
}
|
|
360
|
-
}
|
|
361
|
-
if (!strategySet.has(moduleName) && !indicatorSet.has(moduleName)) {
|
|
422
|
+
} catch (error) {
|
|
362
423
|
import_logger2.logger.warn(
|
|
363
|
-
'
|
|
364
|
-
moduleName
|
|
424
|
+
'Failed to load plugin "%s": %s',
|
|
425
|
+
moduleName,
|
|
426
|
+
String(error)
|
|
365
427
|
);
|
|
366
428
|
}
|
|
367
|
-
} catch (error) {
|
|
368
|
-
import_logger2.logger.warn(
|
|
369
|
-
'Failed to load plugin "%s": %s',
|
|
370
|
-
moduleName,
|
|
371
|
-
String(error)
|
|
372
|
-
);
|
|
373
429
|
}
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
430
|
+
})();
|
|
431
|
+
}
|
|
432
|
+
await state.pluginsLoadPromise;
|
|
377
433
|
};
|
|
378
|
-
var ensureIndicatorPluginsLoaded = ensureStrategyPluginsLoaded;
|
|
379
|
-
var getStrategyCreator = async (name) => {
|
|
380
|
-
await ensureStrategyPluginsLoaded();
|
|
381
|
-
|
|
434
|
+
var ensureIndicatorPluginsLoaded = async (cwd = getTradejsProjectCwd()) => ensureStrategyPluginsLoaded(cwd);
|
|
435
|
+
var getStrategyCreator = async (name, cwd = getTradejsProjectCwd()) => {
|
|
436
|
+
await ensureStrategyPluginsLoaded(cwd);
|
|
437
|
+
const { state } = getStrategyRegistryState(cwd);
|
|
438
|
+
return state.strategyCreators.get(name);
|
|
382
439
|
};
|
|
383
|
-
var getAvailableStrategyNames = async () => {
|
|
384
|
-
await ensureStrategyPluginsLoaded();
|
|
385
|
-
|
|
440
|
+
var getAvailableStrategyNames = async (cwd = getTradejsProjectCwd()) => {
|
|
441
|
+
await ensureStrategyPluginsLoaded(cwd);
|
|
442
|
+
const { state } = getStrategyRegistryState(cwd);
|
|
443
|
+
return [...state.strategyCreators.keys()].sort((a, b) => a.localeCompare(b));
|
|
386
444
|
};
|
|
387
|
-
var getRegisteredStrategies = () => {
|
|
388
|
-
|
|
445
|
+
var getRegisteredStrategies = (cwd = getTradejsProjectCwd()) => {
|
|
446
|
+
const { state } = getStrategyRegistryState(cwd);
|
|
447
|
+
return Object.fromEntries(state.strategyCreators.entries());
|
|
389
448
|
};
|
|
390
|
-
var getRegisteredManifests = () => {
|
|
391
|
-
|
|
449
|
+
var getRegisteredManifests = (cwd = getTradejsProjectCwd()) => {
|
|
450
|
+
const { state } = getStrategyRegistryState(cwd);
|
|
451
|
+
return [...state.strategyManifestsMap.values()];
|
|
392
452
|
};
|
|
393
|
-
var getStrategyManifest = (name) => {
|
|
394
|
-
|
|
453
|
+
var getStrategyManifest = (name, cwd = getTradejsProjectCwd()) => {
|
|
454
|
+
if (!name) {
|
|
455
|
+
return void 0;
|
|
456
|
+
}
|
|
457
|
+
const { state } = getStrategyRegistryState(cwd);
|
|
458
|
+
return state.strategyManifestsMap.get(name);
|
|
395
459
|
};
|
|
396
|
-
var isKnownStrategy = (name) => {
|
|
397
|
-
|
|
460
|
+
var isKnownStrategy = (name, cwd = getTradejsProjectCwd()) => {
|
|
461
|
+
const { state } = getStrategyRegistryState(cwd);
|
|
462
|
+
return state.strategyCreators.has(name);
|
|
398
463
|
};
|
|
399
|
-
var registerStrategyEntries = (entries) => {
|
|
400
|
-
|
|
464
|
+
var registerStrategyEntries = (entries, cwd = getTradejsProjectCwd()) => {
|
|
465
|
+
const { state } = getStrategyRegistryState(cwd);
|
|
466
|
+
registerEntries(entries, "runtime", state);
|
|
401
467
|
};
|
|
402
|
-
var resetStrategyRegistryCache = () => {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
468
|
+
var resetStrategyRegistryCache = (cwd) => {
|
|
469
|
+
const normalizedCwd = String(cwd ?? "").trim();
|
|
470
|
+
if (!normalizedCwd) {
|
|
471
|
+
registryStateByProjectRoot.clear();
|
|
472
|
+
(0, import_indicators.resetIndicatorRegistryCache)();
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const projectRoot = getTradejsProjectCwd(normalizedCwd);
|
|
476
|
+
registryStateByProjectRoot.delete(projectRoot);
|
|
477
|
+
(0, import_indicators.resetIndicatorRegistryCache)(projectRoot);
|
|
407
478
|
};
|
|
408
479
|
var strategies = new Proxy(
|
|
409
480
|
{},
|
|
@@ -412,10 +483,10 @@ var strategies = new Proxy(
|
|
|
412
483
|
if (typeof property !== "string") {
|
|
413
484
|
return void 0;
|
|
414
485
|
}
|
|
415
|
-
return strategyCreators.get(property);
|
|
486
|
+
return getStrategyRegistryState().state.strategyCreators.get(property);
|
|
416
487
|
},
|
|
417
488
|
ownKeys: () => {
|
|
418
|
-
return [...strategyCreators.keys()];
|
|
489
|
+
return [...getStrategyRegistryState().state.strategyCreators.keys()];
|
|
419
490
|
},
|
|
420
491
|
getOwnPropertyDescriptor: () => ({
|
|
421
492
|
enumerable: true,
|
package/dist/registry.mjs
CHANGED
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
registerStrategyEntries,
|
|
12
12
|
resetStrategyRegistryCache,
|
|
13
13
|
strategies
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
14
|
+
} from "./chunk-ZY6ULOWK.mjs";
|
|
15
|
+
import "./chunk-P2ZUWONT.mjs";
|
|
16
16
|
import "./chunk-6DZX6EAA.mjs";
|
|
17
17
|
export {
|
|
18
18
|
ensureIndicatorPluginsLoaded,
|