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

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.mjs CHANGED
@@ -14,8 +14,7 @@ import {
14
14
  runAiPrompt,
15
15
  runAiPromptLocal,
16
16
  trimSeriesDeep
17
- } from "./chunk-733VVTWU.mjs";
18
- import "./chunk-MEZIXBZ3.mjs";
17
+ } from "./chunk-C3KRBNUR.mjs";
19
18
  import "./chunk-LZDXRXIU.mjs";
20
19
  import "./chunk-Y6FXYEAI.mjs";
21
20
  export {
package/dist/backtest.mjs CHANGED
@@ -1,17 +1,15 @@
1
- import {
2
- buildMlPayload,
3
- enrichSignalWithMarketContextStages
4
- } from "./chunk-SVAUSZUE.mjs";
5
- import {
6
- buildAiPayload
7
- } from "./chunk-733VVTWU.mjs";
8
1
  import {
9
2
  BUILTIN_CONNECTOR_NAMES,
10
3
  getConnectorCreatorByName
11
4
  } from "./chunk-QVKUROR2.mjs";
12
5
  import {
6
+ buildMlPayload,
7
+ enrichSignalWithMarketContextStages
8
+ } from "./chunk-B6X2HEGL.mjs";
9
+ import {
10
+ buildAiPayload,
13
11
  getStrategyCreator
14
- } from "./chunk-MEZIXBZ3.mjs";
12
+ } from "./chunk-C3KRBNUR.mjs";
15
13
  import {
16
14
  getTradejsProjectCwd
17
15
  } from "./chunk-LZDXRXIU.mjs";
@@ -1,13 +1,11 @@
1
1
  import {
2
2
  askAI,
3
+ getStrategyManifest,
3
4
  getStrategyProfileMlAdapter,
4
5
  resolveStrategyPolicyProfile,
5
- runAiPromptLocal
6
- } from "./chunk-733VVTWU.mjs";
7
- import {
8
- getStrategyManifest,
6
+ runAiPromptLocal,
9
7
  setStrategyRuntimeFactory
10
- } from "./chunk-MEZIXBZ3.mjs";
8
+ } from "./chunk-C3KRBNUR.mjs";
11
9
  import {
12
10
  getTradejsProjectCwd,
13
11
  loadTradejsConfig
@@ -1,6 +1,9 @@
1
1
  import {
2
- getStrategyManifest
3
- } from "./chunk-MEZIXBZ3.mjs";
2
+ getTradejsProjectCwd,
3
+ importTradejsModule,
4
+ loadTradejsConfig,
5
+ resolvePluginModuleSpecifier
6
+ } from "./chunk-LZDXRXIU.mjs";
4
7
 
5
8
  // src/ai.ts
6
9
  import {
@@ -581,6 +584,278 @@ var buildAiMarketContext = (signal) => ({
581
584
  }
582
585
  });
583
586
 
587
+ // src/strategy/manifests.ts
588
+ import {
589
+ registerIndicatorEntries,
590
+ resetIndicatorRegistryCache
591
+ } from "@tradejs/core/indicators";
592
+ import { logger } from "@tradejs/infra/logger";
593
+ var SHARED_STRATEGY_REGISTRY_KEY = "__tradejsNodeSharedStrategyRegistryV1__";
594
+ var sharedRegistryScope = globalThis;
595
+ var sharedStrategyRegistry = sharedRegistryScope[SHARED_STRATEGY_REGISTRY_KEY] ?? (sharedRegistryScope[SHARED_STRATEGY_REGISTRY_KEY] = {
596
+ registryStateByProjectRoot: /* @__PURE__ */ new Map()
597
+ });
598
+ var createStrategyRegistryState = () => ({
599
+ strategyCreators: /* @__PURE__ */ new Map(),
600
+ strategyManifestsMap: /* @__PURE__ */ new Map(),
601
+ strategyEntriesMap: /* @__PURE__ */ new Map(),
602
+ strategySourcesMap: /* @__PURE__ */ new Map(),
603
+ pluginsLoadPromise: null
604
+ });
605
+ var registryStateByProjectRoot = sharedStrategyRegistry.registryStateByProjectRoot;
606
+ var getStrategyRegistryState = (cwd = getTradejsProjectCwd()) => {
607
+ const projectRoot = getTradejsProjectCwd(cwd);
608
+ let state = registryStateByProjectRoot.get(projectRoot);
609
+ if (!state) {
610
+ state = createStrategyRegistryState();
611
+ registryStateByProjectRoot.set(projectRoot, state);
612
+ }
613
+ return {
614
+ projectRoot,
615
+ state
616
+ };
617
+ };
618
+ var toUniqueModules = (modules = []) => [
619
+ ...new Set(modules.map((moduleName) => moduleName.trim()).filter(Boolean))
620
+ ];
621
+ var getConfiguredPluginModuleNames = async (cwd = getTradejsProjectCwd()) => {
622
+ const config = await loadTradejsConfig(cwd);
623
+ return {
624
+ strategyModules: toUniqueModules(config.strategies),
625
+ indicatorModules: toUniqueModules(config.indicators)
626
+ };
627
+ };
628
+ var extractModuleEntries = (moduleExport, key) => {
629
+ if (!moduleExport || typeof moduleExport !== "object") {
630
+ return null;
631
+ }
632
+ const candidate = moduleExport;
633
+ if (Array.isArray(candidate[key])) {
634
+ return candidate[key];
635
+ }
636
+ const defaultExport = candidate.default;
637
+ if (defaultExport && Array.isArray(defaultExport[key])) {
638
+ return defaultExport[key];
639
+ }
640
+ return null;
641
+ };
642
+ var extractStrategyPluginDefinition = (moduleExport) => {
643
+ const strategyEntries = extractModuleEntries(
644
+ moduleExport,
645
+ "strategyEntries"
646
+ );
647
+ return strategyEntries ? { strategyEntries } : null;
648
+ };
649
+ var extractIndicatorPluginDefinition = (moduleExport) => {
650
+ const indicatorEntries = extractModuleEntries(
651
+ moduleExport,
652
+ "indicatorEntries"
653
+ );
654
+ return indicatorEntries ? { indicatorEntries } : null;
655
+ };
656
+ var registerEntries = (entries, source, state) => {
657
+ for (const entry of entries) {
658
+ const strategyName = entry.manifest?.name;
659
+ if (!strategyName) {
660
+ logger.warn("Skip strategy entry without name from %s", source);
661
+ continue;
662
+ }
663
+ if (state.strategyCreators.has(strategyName)) {
664
+ logger.warn(
665
+ 'Skip duplicate strategy "%s" from %s: already registered',
666
+ strategyName,
667
+ source
668
+ );
669
+ continue;
670
+ }
671
+ state.strategyManifestsMap.set(strategyName, entry.manifest);
672
+ state.strategyEntriesMap.set(strategyName, entry);
673
+ state.strategySourcesMap.set(strategyName, source);
674
+ materializeStrategyCreator(strategyName, state);
675
+ }
676
+ };
677
+ var materializeStrategyCreator = (strategyName, state) => {
678
+ if (state.strategyCreators.has(strategyName) || !sharedStrategyRegistry.strategyRuntimeFactory) {
679
+ return;
680
+ }
681
+ const entry = state.strategyEntriesMap.get(strategyName);
682
+ if (!entry) return;
683
+ state.strategyCreators.set(
684
+ strategyName,
685
+ sharedStrategyRegistry.strategyRuntimeFactory({
686
+ strategyName,
687
+ defaults: entry.defaults,
688
+ createCore: entry.createCore,
689
+ manifest: entry.manifest,
690
+ detectorKey: entry.detectorKey,
691
+ detectorNoSignalSkipReason: entry.detectorNoSignalSkipReason,
692
+ resolveRegisteredManifest: (name) => state.strategyManifestsMap.get(name)
693
+ })
694
+ );
695
+ };
696
+ var setStrategyRuntimeFactory = (factory) => {
697
+ sharedStrategyRegistry.strategyRuntimeFactory = factory;
698
+ for (const state of registryStateByProjectRoot.values()) {
699
+ for (const strategyName of state.strategyEntriesMap.keys()) {
700
+ materializeStrategyCreator(strategyName, state);
701
+ }
702
+ }
703
+ };
704
+ var importStrategyPluginModule = async (moduleName, cwd = getTradejsProjectCwd()) => {
705
+ if (typeof importTradejsModule === "function") {
706
+ return importTradejsModule(moduleName, cwd);
707
+ }
708
+ return import(
709
+ /* webpackIgnore: true */
710
+ moduleName
711
+ );
712
+ };
713
+ var ensureStrategyPluginsLoaded = async (cwd = getTradejsProjectCwd()) => {
714
+ const { projectRoot, state } = getStrategyRegistryState(cwd);
715
+ if (!state.pluginsLoadPromise) {
716
+ resetIndicatorRegistryCache(projectRoot);
717
+ state.pluginsLoadPromise = (async () => {
718
+ const { strategyModules, indicatorModules } = await getConfiguredPluginModuleNames(projectRoot);
719
+ const strategySet = new Set(strategyModules);
720
+ const indicatorSet = new Set(indicatorModules);
721
+ const pluginModuleNames = [
722
+ .../* @__PURE__ */ new Set([...strategyModules, ...indicatorModules])
723
+ ];
724
+ if (!pluginModuleNames.length) {
725
+ return;
726
+ }
727
+ for (const moduleName of pluginModuleNames) {
728
+ try {
729
+ const resolvedModuleName = resolvePluginModuleSpecifier(
730
+ moduleName,
731
+ projectRoot
732
+ );
733
+ const moduleExport = await importStrategyPluginModule(
734
+ resolvedModuleName,
735
+ projectRoot
736
+ );
737
+ if (strategySet.has(moduleName)) {
738
+ const pluginDefinition = extractStrategyPluginDefinition(moduleExport);
739
+ if (!pluginDefinition) {
740
+ logger.warn(
741
+ 'Skip strategy plugin "%s": export { strategyEntries } is missing',
742
+ moduleName
743
+ );
744
+ } else {
745
+ registerEntries(
746
+ pluginDefinition.strategyEntries,
747
+ moduleName,
748
+ state
749
+ );
750
+ }
751
+ }
752
+ if (indicatorSet.has(moduleName)) {
753
+ const indicatorPluginDefinition = extractIndicatorPluginDefinition(moduleExport);
754
+ if (!indicatorPluginDefinition) {
755
+ logger.warn(
756
+ 'Skip indicator plugin "%s": export { indicatorEntries } is missing',
757
+ moduleName
758
+ );
759
+ } else {
760
+ registerIndicatorEntries(
761
+ indicatorPluginDefinition.indicatorEntries,
762
+ moduleName,
763
+ projectRoot
764
+ );
765
+ }
766
+ }
767
+ if (!strategySet.has(moduleName) && !indicatorSet.has(moduleName)) {
768
+ logger.warn(
769
+ 'Skip plugin "%s": no strategy/indicator sections requested in config',
770
+ moduleName
771
+ );
772
+ }
773
+ } catch (error) {
774
+ logger.warn(
775
+ 'Failed to load plugin "%s": %s',
776
+ moduleName,
777
+ String(error)
778
+ );
779
+ }
780
+ }
781
+ })();
782
+ }
783
+ await state.pluginsLoadPromise;
784
+ };
785
+ var ensureIndicatorPluginsLoaded = async (cwd = getTradejsProjectCwd()) => ensureStrategyPluginsLoaded(cwd);
786
+ var getStrategyCreator = async (name, cwd = getTradejsProjectCwd()) => {
787
+ await ensureStrategyPluginsLoaded(cwd);
788
+ const { state } = getStrategyRegistryState(cwd);
789
+ return state.strategyCreators.get(name);
790
+ };
791
+ var getStrategyDefaults = async (name, cwd = getTradejsProjectCwd()) => {
792
+ await ensureStrategyPluginsLoaded(cwd);
793
+ const { state } = getStrategyRegistryState(cwd);
794
+ return state.strategyEntriesMap.get(name)?.defaults;
795
+ };
796
+ var getStrategyPluginSource = async (name, cwd = getTradejsProjectCwd()) => {
797
+ await ensureStrategyPluginsLoaded(cwd);
798
+ const { state } = getStrategyRegistryState(cwd);
799
+ return state.strategySourcesMap.get(name);
800
+ };
801
+ var getAvailableStrategyNames = async (cwd = getTradejsProjectCwd()) => {
802
+ await ensureStrategyPluginsLoaded(cwd);
803
+ const { state } = getStrategyRegistryState(cwd);
804
+ return [...state.strategyCreators.keys()].sort((a, b) => a.localeCompare(b));
805
+ };
806
+ var getRegisteredStrategies = (cwd = getTradejsProjectCwd()) => {
807
+ const { state } = getStrategyRegistryState(cwd);
808
+ return Object.fromEntries(state.strategyCreators.entries());
809
+ };
810
+ var getRegisteredManifests = (cwd = getTradejsProjectCwd()) => {
811
+ const { state } = getStrategyRegistryState(cwd);
812
+ return [...state.strategyManifestsMap.values()];
813
+ };
814
+ var getStrategyManifest = (name, cwd = getTradejsProjectCwd()) => {
815
+ if (!name) {
816
+ return void 0;
817
+ }
818
+ const { state } = getStrategyRegistryState(cwd);
819
+ return state.strategyManifestsMap.get(name);
820
+ };
821
+ var isKnownStrategy = (name, cwd = getTradejsProjectCwd()) => {
822
+ const { state } = getStrategyRegistryState(cwd);
823
+ return state.strategyCreators.has(name);
824
+ };
825
+ var registerStrategyEntries = (entries, cwd = getTradejsProjectCwd()) => {
826
+ const { state } = getStrategyRegistryState(cwd);
827
+ registerEntries(entries, "runtime", state);
828
+ };
829
+ var resetStrategyRegistryCache = (cwd) => {
830
+ const normalizedCwd = String(cwd ?? "").trim();
831
+ if (!normalizedCwd) {
832
+ registryStateByProjectRoot.clear();
833
+ resetIndicatorRegistryCache();
834
+ return;
835
+ }
836
+ const projectRoot = getTradejsProjectCwd(normalizedCwd);
837
+ registryStateByProjectRoot.delete(projectRoot);
838
+ resetIndicatorRegistryCache(projectRoot);
839
+ };
840
+ var strategies = new Proxy(
841
+ {},
842
+ {
843
+ get: (_target, property) => {
844
+ if (typeof property !== "string") {
845
+ return void 0;
846
+ }
847
+ return getStrategyRegistryState().state.strategyCreators.get(property);
848
+ },
849
+ ownKeys: () => {
850
+ return [...getStrategyRegistryState().state.strategyCreators.keys()];
851
+ },
852
+ getOwnPropertyDescriptor: () => ({
853
+ enumerable: true,
854
+ configurable: true
855
+ })
856
+ }
857
+ );
858
+
584
859
  // src/strategy/policyProfiles.ts
585
860
  var profileMatches = (profile, universe, assetClass) => {
586
861
  const { appliesTo } = profile;
@@ -1171,6 +1446,20 @@ export {
1171
1446
  MAX_AI_SERIES_POINTS,
1172
1447
  trimSeriesDeep,
1173
1448
  buildCompactAiIndicatorsSnapshot,
1449
+ setStrategyRuntimeFactory,
1450
+ ensureStrategyPluginsLoaded,
1451
+ ensureIndicatorPluginsLoaded,
1452
+ getStrategyCreator,
1453
+ getStrategyDefaults,
1454
+ getStrategyPluginSource,
1455
+ getAvailableStrategyNames,
1456
+ getRegisteredStrategies,
1457
+ getRegisteredManifests,
1458
+ getStrategyManifest,
1459
+ isKnownStrategy,
1460
+ registerStrategyEntries,
1461
+ resetStrategyRegistryCache,
1462
+ strategies,
1174
1463
  resolveStrategyPolicyProfile,
1175
1464
  getStrategyProfileMlAdapter,
1176
1465
  DEFAULT_AI_MODEL,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getStrategyCreator,
3
3
  getStrategyPluginSource
4
- } from "./chunk-MEZIXBZ3.mjs";
4
+ } from "./chunk-C3KRBNUR.mjs";
5
5
  import {
6
6
  loadTradejsConfig
7
7
  } from "./chunk-LZDXRXIU.mjs";
package/dist/cli.mjs CHANGED
@@ -4,11 +4,9 @@ import {
4
4
  SCREENSHOT_CONCURRENCY_LIMIT
5
5
  } from "./chunk-KMJQQ53K.mjs";
6
6
  import {
7
- askAI
8
- } from "./chunk-733VVTWU.mjs";
9
- import {
7
+ askAI,
10
8
  ensureStrategyPluginsLoaded
11
- } from "./chunk-MEZIXBZ3.mjs";
9
+ } from "./chunk-C3KRBNUR.mjs";
12
10
  import {
13
11
  getTradejsProjectCwd,
14
12
  loadTradejsConfig
package/dist/registry.mjs CHANGED
@@ -1,5 +1,4 @@
1
- import "./chunk-SVAUSZUE.mjs";
2
- import "./chunk-733VVTWU.mjs";
1
+ import "./chunk-B6X2HEGL.mjs";
3
2
  import {
4
3
  ensureIndicatorPluginsLoaded,
5
4
  ensureStrategyPluginsLoaded,
@@ -13,7 +12,7 @@ import {
13
12
  registerStrategyEntries,
14
13
  resetStrategyRegistryCache,
15
14
  strategies
16
- } from "./chunk-MEZIXBZ3.mjs";
15
+ } from "./chunk-C3KRBNUR.mjs";
17
16
  import "./chunk-LZDXRXIU.mjs";
18
17
  import "./chunk-Y6FXYEAI.mjs";
19
18
  export {