@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/strategies.js
CHANGED
|
@@ -5546,7 +5546,7 @@ var init_aiShared = __esm({
|
|
|
5546
5546
|
});
|
|
5547
5547
|
|
|
5548
5548
|
// src/tradejsConfig.ts
|
|
5549
|
-
var import_fs, import_path, import_module, import_url, import_logger2, CONFIG_FILE_NAMES, TS_MODULE_RE, cachedByCwd, announcedConfigFile, tsNodeRegistered, getTradejsProjectCwd, normalizeConfig, getRequireFn, ensureTsNodeRegistered, toImportSpecifier, isTsModulePath, isRelativeModulePath, isBareModuleSpecifier, importConfigFile, importTradejsModule, resolveExportedConfig, findConfigFilePath, resolvePluginModuleSpecifier, loadTradejsConfig;
|
|
5549
|
+
var import_fs, import_path, import_module, import_url, import_logger2, CONFIG_FILE_NAMES, TS_MODULE_RE, cachedByCwd, announcedConfigFile, tsNodeRegistered, tsconfigPathsRegisteredByCwd, getTradejsProjectCwd, normalizeConfig, getRequireFn, ensureTsNodeRegistered, ensureTsconfigPathsRegistered, toImportSpecifier, isTsModulePath, isRelativeModulePath, isBareModuleSpecifier, importConfigFile, importTradejsModule, resolveExportedConfig, findConfigFilePath, resolvePluginModuleSpecifier, loadTradejsConfig;
|
|
5550
5550
|
var init_tradejsConfig = __esm({
|
|
5551
5551
|
"src/tradejsConfig.ts"() {
|
|
5552
5552
|
"use strict";
|
|
@@ -5566,6 +5566,7 @@ var init_tradejsConfig = __esm({
|
|
|
5566
5566
|
cachedByCwd = /* @__PURE__ */ new Map();
|
|
5567
5567
|
announcedConfigFile = /* @__PURE__ */ new Set();
|
|
5568
5568
|
tsNodeRegistered = false;
|
|
5569
|
+
tsconfigPathsRegisteredByCwd = /* @__PURE__ */ new Set();
|
|
5569
5570
|
getTradejsProjectCwd = (cwd) => {
|
|
5570
5571
|
const explicit = String(cwd ?? "").trim();
|
|
5571
5572
|
if (explicit) {
|
|
@@ -5607,6 +5608,28 @@ var init_tradejsConfig = __esm({
|
|
|
5607
5608
|
});
|
|
5608
5609
|
tsNodeRegistered = true;
|
|
5609
5610
|
};
|
|
5611
|
+
ensureTsconfigPathsRegistered = async (cwd = getTradejsProjectCwd()) => {
|
|
5612
|
+
const projectRoot = getTradejsProjectCwd(cwd);
|
|
5613
|
+
if (tsconfigPathsRegisteredByCwd.has(projectRoot)) {
|
|
5614
|
+
return;
|
|
5615
|
+
}
|
|
5616
|
+
const tsconfigPathsModule = await import("tsconfig-paths");
|
|
5617
|
+
const loadConfig = tsconfigPathsModule.loadConfig;
|
|
5618
|
+
const register = tsconfigPathsModule.register;
|
|
5619
|
+
if (typeof loadConfig !== "function" || typeof register !== "function") {
|
|
5620
|
+
return;
|
|
5621
|
+
}
|
|
5622
|
+
const loadedConfig = loadConfig(projectRoot);
|
|
5623
|
+
if (loadedConfig.resultType !== "success") {
|
|
5624
|
+
return;
|
|
5625
|
+
}
|
|
5626
|
+
register({
|
|
5627
|
+
baseUrl: loadedConfig.absoluteBaseUrl,
|
|
5628
|
+
paths: loadedConfig.paths,
|
|
5629
|
+
addMatchAll: false
|
|
5630
|
+
});
|
|
5631
|
+
tsconfigPathsRegisteredByCwd.add(projectRoot);
|
|
5632
|
+
};
|
|
5610
5633
|
toImportSpecifier = (moduleName) => {
|
|
5611
5634
|
if (moduleName.startsWith("file://")) {
|
|
5612
5635
|
return moduleName;
|
|
@@ -5634,6 +5657,7 @@ var init_tradejsConfig = __esm({
|
|
|
5634
5657
|
if (ext === ".ts" || ext === ".mts") {
|
|
5635
5658
|
const requireFn = getRequireFn(import_path.default.dirname(configFilePath));
|
|
5636
5659
|
await ensureTsNodeRegistered();
|
|
5660
|
+
await ensureTsconfigPathsRegistered(import_path.default.dirname(configFilePath));
|
|
5637
5661
|
return requireFn(configFilePath);
|
|
5638
5662
|
}
|
|
5639
5663
|
return import(
|
|
@@ -5641,7 +5665,7 @@ var init_tradejsConfig = __esm({
|
|
|
5641
5665
|
configFileUrl
|
|
5642
5666
|
);
|
|
5643
5667
|
};
|
|
5644
|
-
importTradejsModule = async (moduleName) => {
|
|
5668
|
+
importTradejsModule = async (moduleName, cwd = getTradejsProjectCwd()) => {
|
|
5645
5669
|
const normalized = String(moduleName ?? "").trim();
|
|
5646
5670
|
if (!normalized) {
|
|
5647
5671
|
return {};
|
|
@@ -5655,13 +5679,15 @@ var init_tradejsConfig = __esm({
|
|
|
5655
5679
|
}
|
|
5656
5680
|
}
|
|
5657
5681
|
const requireFn = getRequireFn(
|
|
5658
|
-
import_path.default.isAbsolute(modulePath) ? import_path.default.dirname(modulePath) :
|
|
5682
|
+
import_path.default.isAbsolute(modulePath) ? import_path.default.dirname(modulePath) : cwd
|
|
5659
5683
|
);
|
|
5660
5684
|
if (isTsModulePath(modulePath)) {
|
|
5661
5685
|
await ensureTsNodeRegistered();
|
|
5686
|
+
await ensureTsconfigPathsRegistered(cwd);
|
|
5662
5687
|
return requireFn(modulePath);
|
|
5663
5688
|
}
|
|
5664
5689
|
if (isBareModuleSpecifier(normalized)) {
|
|
5690
|
+
await ensureTsconfigPathsRegistered(cwd);
|
|
5665
5691
|
return requireFn(normalized);
|
|
5666
5692
|
}
|
|
5667
5693
|
try {
|
|
@@ -5672,6 +5698,7 @@ var init_tradejsConfig = __esm({
|
|
|
5672
5698
|
} catch (error) {
|
|
5673
5699
|
if (isTsModulePath(modulePath)) {
|
|
5674
5700
|
await ensureTsNodeRegistered();
|
|
5701
|
+
await ensureTsconfigPathsRegistered(cwd);
|
|
5675
5702
|
return requireFn(modulePath);
|
|
5676
5703
|
}
|
|
5677
5704
|
throw error;
|
|
@@ -5751,7 +5778,7 @@ var init_tradejsConfig = __esm({
|
|
|
5751
5778
|
});
|
|
5752
5779
|
|
|
5753
5780
|
// src/strategy/manifests.ts
|
|
5754
|
-
var import_indicators, import_logger3,
|
|
5781
|
+
var import_indicators, import_logger3, createStrategyRegistryState, registryStateByProjectRoot, getStrategyRegistryState, toUniqueModules, getConfiguredPluginModuleNames, extractModuleEntries, extractStrategyPluginDefinition, extractIndicatorPluginDefinition, registerEntries, importStrategyPluginModule, ensureStrategyPluginsLoaded, ensureIndicatorPluginsLoaded, getStrategyCreator, getAvailableStrategyNames, getRegisteredStrategies, getRegisteredManifests, getStrategyManifest, isKnownStrategy, registerStrategyEntries, resetStrategyRegistryCache, strategies;
|
|
5755
5782
|
var init_manifests = __esm({
|
|
5756
5783
|
"src/strategy/manifests.ts"() {
|
|
5757
5784
|
"use strict";
|
|
@@ -5759,14 +5786,29 @@ var init_manifests = __esm({
|
|
|
5759
5786
|
import_logger3 = require("@tradejs/infra/logger");
|
|
5760
5787
|
init_tradejsConfig();
|
|
5761
5788
|
init_tradejsConfig();
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5789
|
+
createStrategyRegistryState = () => ({
|
|
5790
|
+
strategyCreators: /* @__PURE__ */ new Map(),
|
|
5791
|
+
strategyManifestsMap: /* @__PURE__ */ new Map(),
|
|
5792
|
+
pluginsLoadPromise: null
|
|
5793
|
+
});
|
|
5794
|
+
registryStateByProjectRoot = /* @__PURE__ */ new Map();
|
|
5795
|
+
getStrategyRegistryState = (cwd = getTradejsProjectCwd()) => {
|
|
5796
|
+
const projectRoot = getTradejsProjectCwd(cwd);
|
|
5797
|
+
let state = registryStateByProjectRoot.get(projectRoot);
|
|
5798
|
+
if (!state) {
|
|
5799
|
+
state = createStrategyRegistryState();
|
|
5800
|
+
registryStateByProjectRoot.set(projectRoot, state);
|
|
5801
|
+
}
|
|
5802
|
+
return {
|
|
5803
|
+
projectRoot,
|
|
5804
|
+
state
|
|
5805
|
+
};
|
|
5806
|
+
};
|
|
5765
5807
|
toUniqueModules = (modules = []) => [
|
|
5766
5808
|
...new Set(modules.map((moduleName) => moduleName.trim()).filter(Boolean))
|
|
5767
5809
|
];
|
|
5768
|
-
getConfiguredPluginModuleNames = async () => {
|
|
5769
|
-
const config = await loadTradejsConfig();
|
|
5810
|
+
getConfiguredPluginModuleNames = async (cwd = getTradejsProjectCwd()) => {
|
|
5811
|
+
const config = await loadTradejsConfig(cwd);
|
|
5770
5812
|
return {
|
|
5771
5813
|
strategyModules: toUniqueModules(config.strategies),
|
|
5772
5814
|
indicatorModules: toUniqueModules(config.indicators)
|
|
@@ -5800,14 +5842,14 @@ var init_manifests = __esm({
|
|
|
5800
5842
|
);
|
|
5801
5843
|
return indicatorEntries ? { indicatorEntries } : null;
|
|
5802
5844
|
};
|
|
5803
|
-
registerEntries = (entries, source) => {
|
|
5845
|
+
registerEntries = (entries, source, state) => {
|
|
5804
5846
|
for (const entry of entries) {
|
|
5805
5847
|
const strategyName = entry.manifest?.name;
|
|
5806
5848
|
if (!strategyName) {
|
|
5807
5849
|
import_logger3.logger.warn("Skip strategy entry without name from %s", source);
|
|
5808
5850
|
continue;
|
|
5809
5851
|
}
|
|
5810
|
-
if (strategyCreators.has(strategyName)) {
|
|
5852
|
+
if (state.strategyCreators.has(strategyName)) {
|
|
5811
5853
|
import_logger3.logger.warn(
|
|
5812
5854
|
'Skip duplicate strategy "%s" from %s: already registered',
|
|
5813
5855
|
strategyName,
|
|
@@ -5815,106 +5857,135 @@ var init_manifests = __esm({
|
|
|
5815
5857
|
);
|
|
5816
5858
|
continue;
|
|
5817
5859
|
}
|
|
5818
|
-
strategyCreators.set(strategyName, entry.creator);
|
|
5819
|
-
strategyManifestsMap.set(strategyName, entry.manifest);
|
|
5860
|
+
state.strategyCreators.set(strategyName, entry.creator);
|
|
5861
|
+
state.strategyManifestsMap.set(strategyName, entry.manifest);
|
|
5820
5862
|
}
|
|
5821
5863
|
};
|
|
5822
|
-
importStrategyPluginModule = async (moduleName) => {
|
|
5864
|
+
importStrategyPluginModule = async (moduleName, cwd = getTradejsProjectCwd()) => {
|
|
5823
5865
|
if (typeof importTradejsModule === "function") {
|
|
5824
|
-
return importTradejsModule(moduleName);
|
|
5866
|
+
return importTradejsModule(moduleName, cwd);
|
|
5825
5867
|
}
|
|
5826
5868
|
return import(
|
|
5827
5869
|
/* webpackIgnore: true */
|
|
5828
5870
|
moduleName
|
|
5829
5871
|
);
|
|
5830
5872
|
};
|
|
5831
|
-
ensureStrategyPluginsLoaded = async () => {
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5852
|
-
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
|
|
5873
|
+
ensureStrategyPluginsLoaded = async (cwd = getTradejsProjectCwd()) => {
|
|
5874
|
+
const { projectRoot, state } = getStrategyRegistryState(cwd);
|
|
5875
|
+
if (!state.pluginsLoadPromise) {
|
|
5876
|
+
(0, import_indicators.resetIndicatorRegistryCache)(projectRoot);
|
|
5877
|
+
state.pluginsLoadPromise = (async () => {
|
|
5878
|
+
const { strategyModules, indicatorModules } = await getConfiguredPluginModuleNames(projectRoot);
|
|
5879
|
+
const strategySet = new Set(strategyModules);
|
|
5880
|
+
const indicatorSet = new Set(indicatorModules);
|
|
5881
|
+
const pluginModuleNames = [
|
|
5882
|
+
.../* @__PURE__ */ new Set([...strategyModules, ...indicatorModules])
|
|
5883
|
+
];
|
|
5884
|
+
if (!pluginModuleNames.length) {
|
|
5885
|
+
return;
|
|
5886
|
+
}
|
|
5887
|
+
for (const moduleName of pluginModuleNames) {
|
|
5888
|
+
try {
|
|
5889
|
+
const resolvedModuleName = resolvePluginModuleSpecifier(
|
|
5890
|
+
moduleName,
|
|
5891
|
+
projectRoot
|
|
5892
|
+
);
|
|
5893
|
+
const moduleExport = await importStrategyPluginModule(
|
|
5894
|
+
resolvedModuleName,
|
|
5895
|
+
projectRoot
|
|
5896
|
+
);
|
|
5897
|
+
if (strategySet.has(moduleName)) {
|
|
5898
|
+
const pluginDefinition = extractStrategyPluginDefinition(moduleExport);
|
|
5899
|
+
if (!pluginDefinition) {
|
|
5900
|
+
import_logger3.logger.warn(
|
|
5901
|
+
'Skip strategy plugin "%s": export { strategyEntries } is missing',
|
|
5902
|
+
moduleName
|
|
5903
|
+
);
|
|
5904
|
+
} else {
|
|
5905
|
+
registerEntries(
|
|
5906
|
+
pluginDefinition.strategyEntries,
|
|
5907
|
+
moduleName,
|
|
5908
|
+
state
|
|
5909
|
+
);
|
|
5910
|
+
}
|
|
5856
5911
|
}
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5912
|
+
if (indicatorSet.has(moduleName)) {
|
|
5913
|
+
const indicatorPluginDefinition = extractIndicatorPluginDefinition(moduleExport);
|
|
5914
|
+
if (!indicatorPluginDefinition) {
|
|
5915
|
+
import_logger3.logger.warn(
|
|
5916
|
+
'Skip indicator plugin "%s": export { indicatorEntries } is missing',
|
|
5917
|
+
moduleName
|
|
5918
|
+
);
|
|
5919
|
+
} else {
|
|
5920
|
+
(0, import_indicators.registerIndicatorEntries)(
|
|
5921
|
+
indicatorPluginDefinition.indicatorEntries,
|
|
5922
|
+
moduleName,
|
|
5923
|
+
projectRoot
|
|
5924
|
+
);
|
|
5925
|
+
}
|
|
5926
|
+
}
|
|
5927
|
+
if (!strategySet.has(moduleName) && !indicatorSet.has(moduleName)) {
|
|
5861
5928
|
import_logger3.logger.warn(
|
|
5862
|
-
'Skip
|
|
5863
|
-
moduleName
|
|
5864
|
-
);
|
|
5865
|
-
} else {
|
|
5866
|
-
(0, import_indicators.registerIndicatorEntries)(
|
|
5867
|
-
indicatorPluginDefinition.indicatorEntries,
|
|
5929
|
+
'Skip plugin "%s": no strategy/indicator sections requested in config',
|
|
5868
5930
|
moduleName
|
|
5869
5931
|
);
|
|
5870
5932
|
}
|
|
5871
|
-
}
|
|
5872
|
-
if (!strategySet.has(moduleName) && !indicatorSet.has(moduleName)) {
|
|
5933
|
+
} catch (error) {
|
|
5873
5934
|
import_logger3.logger.warn(
|
|
5874
|
-
'
|
|
5875
|
-
moduleName
|
|
5935
|
+
'Failed to load plugin "%s": %s',
|
|
5936
|
+
moduleName,
|
|
5937
|
+
String(error)
|
|
5876
5938
|
);
|
|
5877
5939
|
}
|
|
5878
|
-
} catch (error) {
|
|
5879
|
-
import_logger3.logger.warn(
|
|
5880
|
-
'Failed to load plugin "%s": %s',
|
|
5881
|
-
moduleName,
|
|
5882
|
-
String(error)
|
|
5883
|
-
);
|
|
5884
5940
|
}
|
|
5885
|
-
}
|
|
5886
|
-
}
|
|
5887
|
-
|
|
5941
|
+
})();
|
|
5942
|
+
}
|
|
5943
|
+
await state.pluginsLoadPromise;
|
|
5888
5944
|
};
|
|
5889
|
-
ensureIndicatorPluginsLoaded = ensureStrategyPluginsLoaded;
|
|
5890
|
-
getStrategyCreator = async (name) => {
|
|
5891
|
-
await ensureStrategyPluginsLoaded();
|
|
5892
|
-
|
|
5945
|
+
ensureIndicatorPluginsLoaded = async (cwd = getTradejsProjectCwd()) => ensureStrategyPluginsLoaded(cwd);
|
|
5946
|
+
getStrategyCreator = async (name, cwd = getTradejsProjectCwd()) => {
|
|
5947
|
+
await ensureStrategyPluginsLoaded(cwd);
|
|
5948
|
+
const { state } = getStrategyRegistryState(cwd);
|
|
5949
|
+
return state.strategyCreators.get(name);
|
|
5893
5950
|
};
|
|
5894
|
-
getAvailableStrategyNames = async () => {
|
|
5895
|
-
await ensureStrategyPluginsLoaded();
|
|
5896
|
-
|
|
5951
|
+
getAvailableStrategyNames = async (cwd = getTradejsProjectCwd()) => {
|
|
5952
|
+
await ensureStrategyPluginsLoaded(cwd);
|
|
5953
|
+
const { state } = getStrategyRegistryState(cwd);
|
|
5954
|
+
return [...state.strategyCreators.keys()].sort((a, b) => a.localeCompare(b));
|
|
5897
5955
|
};
|
|
5898
|
-
getRegisteredStrategies = () => {
|
|
5899
|
-
|
|
5956
|
+
getRegisteredStrategies = (cwd = getTradejsProjectCwd()) => {
|
|
5957
|
+
const { state } = getStrategyRegistryState(cwd);
|
|
5958
|
+
return Object.fromEntries(state.strategyCreators.entries());
|
|
5900
5959
|
};
|
|
5901
|
-
getRegisteredManifests = () => {
|
|
5902
|
-
|
|
5960
|
+
getRegisteredManifests = (cwd = getTradejsProjectCwd()) => {
|
|
5961
|
+
const { state } = getStrategyRegistryState(cwd);
|
|
5962
|
+
return [...state.strategyManifestsMap.values()];
|
|
5903
5963
|
};
|
|
5904
|
-
getStrategyManifest = (name) => {
|
|
5905
|
-
|
|
5964
|
+
getStrategyManifest = (name, cwd = getTradejsProjectCwd()) => {
|
|
5965
|
+
if (!name) {
|
|
5966
|
+
return void 0;
|
|
5967
|
+
}
|
|
5968
|
+
const { state } = getStrategyRegistryState(cwd);
|
|
5969
|
+
return state.strategyManifestsMap.get(name);
|
|
5906
5970
|
};
|
|
5907
|
-
isKnownStrategy = (name) => {
|
|
5908
|
-
|
|
5971
|
+
isKnownStrategy = (name, cwd = getTradejsProjectCwd()) => {
|
|
5972
|
+
const { state } = getStrategyRegistryState(cwd);
|
|
5973
|
+
return state.strategyCreators.has(name);
|
|
5909
5974
|
};
|
|
5910
|
-
registerStrategyEntries = (entries) => {
|
|
5911
|
-
|
|
5975
|
+
registerStrategyEntries = (entries, cwd = getTradejsProjectCwd()) => {
|
|
5976
|
+
const { state } = getStrategyRegistryState(cwd);
|
|
5977
|
+
registerEntries(entries, "runtime", state);
|
|
5912
5978
|
};
|
|
5913
|
-
resetStrategyRegistryCache = () => {
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5979
|
+
resetStrategyRegistryCache = (cwd) => {
|
|
5980
|
+
const normalizedCwd = String(cwd ?? "").trim();
|
|
5981
|
+
if (!normalizedCwd) {
|
|
5982
|
+
registryStateByProjectRoot.clear();
|
|
5983
|
+
(0, import_indicators.resetIndicatorRegistryCache)();
|
|
5984
|
+
return;
|
|
5985
|
+
}
|
|
5986
|
+
const projectRoot = getTradejsProjectCwd(normalizedCwd);
|
|
5987
|
+
registryStateByProjectRoot.delete(projectRoot);
|
|
5988
|
+
(0, import_indicators.resetIndicatorRegistryCache)(projectRoot);
|
|
5918
5989
|
};
|
|
5919
5990
|
strategies = new Proxy(
|
|
5920
5991
|
{},
|
|
@@ -5923,10 +5994,10 @@ var init_manifests = __esm({
|
|
|
5923
5994
|
if (typeof property !== "string") {
|
|
5924
5995
|
return void 0;
|
|
5925
5996
|
}
|
|
5926
|
-
return strategyCreators.get(property);
|
|
5997
|
+
return getStrategyRegistryState().state.strategyCreators.get(property);
|
|
5927
5998
|
},
|
|
5928
5999
|
ownKeys: () => {
|
|
5929
|
-
return [...strategyCreators.keys()];
|
|
6000
|
+
return [...getStrategyRegistryState().state.strategyCreators.keys()];
|
|
5930
6001
|
},
|
|
5931
6002
|
getOwnPropertyDescriptor: () => ({
|
|
5932
6003
|
enumerable: true,
|
|
@@ -6399,6 +6470,7 @@ var buildMlPayload = (payload) => {
|
|
|
6399
6470
|
};
|
|
6400
6471
|
|
|
6401
6472
|
// src/strategyHelpers/runtime.ts
|
|
6473
|
+
init_tradejsConfig();
|
|
6402
6474
|
var formatAiError = (err) => {
|
|
6403
6475
|
const error = err;
|
|
6404
6476
|
const safeJson = (value) => {
|
|
@@ -6440,7 +6512,8 @@ var enrichSignalWithMl = async ({
|
|
|
6440
6512
|
const mlResult = await (0, import_ml2.fetchMlThreshold)({
|
|
6441
6513
|
strategy,
|
|
6442
6514
|
features,
|
|
6443
|
-
threshold: ml.mlThreshold
|
|
6515
|
+
threshold: ml.mlThreshold,
|
|
6516
|
+
projectRoot: getTradejsProjectCwd()
|
|
6444
6517
|
});
|
|
6445
6518
|
if (mlResult) {
|
|
6446
6519
|
signal.ml = mlResult;
|
|
@@ -6545,6 +6618,7 @@ var createLoadPineScript = (baseDir) => {
|
|
|
6545
6618
|
|
|
6546
6619
|
// src/strategyRuntime.ts
|
|
6547
6620
|
init_manifests();
|
|
6621
|
+
init_tradejsConfig();
|
|
6548
6622
|
|
|
6549
6623
|
// src/strategyHelpers/config.ts
|
|
6550
6624
|
var import_lodash2 = __toESM(require_lodash());
|
|
@@ -6634,10 +6708,151 @@ var getEntrySkipReason = ({
|
|
|
6634
6708
|
}
|
|
6635
6709
|
return "ENTRY_POLICY_BLOCKED";
|
|
6636
6710
|
};
|
|
6711
|
+
var buildHookCtx = ({
|
|
6712
|
+
connector,
|
|
6713
|
+
strategyName,
|
|
6714
|
+
userName,
|
|
6715
|
+
symbol,
|
|
6716
|
+
strategyConfig,
|
|
6717
|
+
env,
|
|
6718
|
+
isConfigFromBacktest
|
|
6719
|
+
}) => ({
|
|
6720
|
+
connector,
|
|
6721
|
+
strategyName,
|
|
6722
|
+
userName,
|
|
6723
|
+
symbol,
|
|
6724
|
+
strategyConfig,
|
|
6725
|
+
env,
|
|
6726
|
+
isConfigFromBacktest
|
|
6727
|
+
});
|
|
6728
|
+
var buildHookEntry = ({
|
|
6729
|
+
decision,
|
|
6730
|
+
runtime
|
|
6731
|
+
}) => ({
|
|
6732
|
+
context: decision.entryContext,
|
|
6733
|
+
orderPlan: decision.orderPlan,
|
|
6734
|
+
signal: decision.signal,
|
|
6735
|
+
runtime: {
|
|
6736
|
+
raw: decision.runtime,
|
|
6737
|
+
resolved: runtime
|
|
6738
|
+
}
|
|
6739
|
+
});
|
|
6740
|
+
var buildHookPolicy = ({
|
|
6741
|
+
quality,
|
|
6742
|
+
makeOrdersEnabled,
|
|
6743
|
+
minAiQuality
|
|
6744
|
+
}) => ({
|
|
6745
|
+
aiQuality: quality,
|
|
6746
|
+
makeOrdersEnabled,
|
|
6747
|
+
minAiQuality
|
|
6748
|
+
});
|
|
6749
|
+
var buildMlHookContext = ({
|
|
6750
|
+
signal,
|
|
6751
|
+
env,
|
|
6752
|
+
ml
|
|
6753
|
+
}) => {
|
|
6754
|
+
if (env === "BACKTEST") {
|
|
6755
|
+
return {
|
|
6756
|
+
config: ml,
|
|
6757
|
+
attempted: false,
|
|
6758
|
+
applied: false,
|
|
6759
|
+
skippedReason: "BACKTEST"
|
|
6760
|
+
};
|
|
6761
|
+
}
|
|
6762
|
+
if (!ml) {
|
|
6763
|
+
return {
|
|
6764
|
+
attempted: false,
|
|
6765
|
+
applied: false,
|
|
6766
|
+
skippedReason: "NO_RUNTIME"
|
|
6767
|
+
};
|
|
6768
|
+
}
|
|
6769
|
+
if (ml.enabled === false) {
|
|
6770
|
+
return {
|
|
6771
|
+
config: ml,
|
|
6772
|
+
attempted: false,
|
|
6773
|
+
applied: false,
|
|
6774
|
+
skippedReason: "DISABLED"
|
|
6775
|
+
};
|
|
6776
|
+
}
|
|
6777
|
+
if (!ml.strategyConfig) {
|
|
6778
|
+
return {
|
|
6779
|
+
config: ml,
|
|
6780
|
+
attempted: false,
|
|
6781
|
+
applied: false,
|
|
6782
|
+
skippedReason: "NO_STRATEGY_CONFIG"
|
|
6783
|
+
};
|
|
6784
|
+
}
|
|
6785
|
+
if (typeof ml.mlThreshold !== "number") {
|
|
6786
|
+
return {
|
|
6787
|
+
config: ml,
|
|
6788
|
+
attempted: false,
|
|
6789
|
+
applied: false,
|
|
6790
|
+
skippedReason: "NO_THRESHOLD"
|
|
6791
|
+
};
|
|
6792
|
+
}
|
|
6793
|
+
if (signal.ml) {
|
|
6794
|
+
return {
|
|
6795
|
+
config: ml,
|
|
6796
|
+
attempted: true,
|
|
6797
|
+
applied: true,
|
|
6798
|
+
result: signal.ml
|
|
6799
|
+
};
|
|
6800
|
+
}
|
|
6801
|
+
return {
|
|
6802
|
+
config: ml,
|
|
6803
|
+
attempted: true,
|
|
6804
|
+
applied: false,
|
|
6805
|
+
skippedReason: "NO_RESULT"
|
|
6806
|
+
};
|
|
6807
|
+
};
|
|
6808
|
+
var buildAiHookContext = ({
|
|
6809
|
+
env,
|
|
6810
|
+
ai,
|
|
6811
|
+
quality
|
|
6812
|
+
}) => {
|
|
6813
|
+
if (env === "BACKTEST") {
|
|
6814
|
+
return {
|
|
6815
|
+
config: ai,
|
|
6816
|
+
attempted: false,
|
|
6817
|
+
applied: false,
|
|
6818
|
+
skippedReason: "BACKTEST"
|
|
6819
|
+
};
|
|
6820
|
+
}
|
|
6821
|
+
if (!ai) {
|
|
6822
|
+
return {
|
|
6823
|
+
attempted: false,
|
|
6824
|
+
applied: false,
|
|
6825
|
+
skippedReason: "NO_RUNTIME"
|
|
6826
|
+
};
|
|
6827
|
+
}
|
|
6828
|
+
if (ai.enabled === false) {
|
|
6829
|
+
return {
|
|
6830
|
+
config: ai,
|
|
6831
|
+
attempted: false,
|
|
6832
|
+
applied: false,
|
|
6833
|
+
skippedReason: "DISABLED"
|
|
6834
|
+
};
|
|
6835
|
+
}
|
|
6836
|
+
if (typeof quality === "number") {
|
|
6837
|
+
return {
|
|
6838
|
+
config: ai,
|
|
6839
|
+
attempted: true,
|
|
6840
|
+
applied: true,
|
|
6841
|
+
quality
|
|
6842
|
+
};
|
|
6843
|
+
}
|
|
6844
|
+
return {
|
|
6845
|
+
config: ai,
|
|
6846
|
+
attempted: true,
|
|
6847
|
+
applied: false,
|
|
6848
|
+
skippedReason: "NO_QUALITY"
|
|
6849
|
+
};
|
|
6850
|
+
};
|
|
6637
6851
|
var handleExitDecision = async ({
|
|
6638
6852
|
connector,
|
|
6639
6853
|
symbol,
|
|
6640
6854
|
decision,
|
|
6855
|
+
market,
|
|
6641
6856
|
onRuntimeError
|
|
6642
6857
|
}) => {
|
|
6643
6858
|
try {
|
|
@@ -6651,7 +6866,8 @@ var handleExitDecision = async ({
|
|
|
6651
6866
|
await onRuntimeError?.({
|
|
6652
6867
|
stage: "closePosition",
|
|
6653
6868
|
error: err,
|
|
6654
|
-
decision
|
|
6869
|
+
decision,
|
|
6870
|
+
market
|
|
6655
6871
|
});
|
|
6656
6872
|
import_logger5.logger.error("close order error: %s %s", symbol, err);
|
|
6657
6873
|
return "ORDER_ERROR";
|
|
@@ -6664,7 +6880,12 @@ var executeEntryDecision = async ({
|
|
|
6664
6880
|
decision,
|
|
6665
6881
|
runtime,
|
|
6666
6882
|
manifest,
|
|
6667
|
-
|
|
6883
|
+
hookCtx,
|
|
6884
|
+
market,
|
|
6885
|
+
entry,
|
|
6886
|
+
policy,
|
|
6887
|
+
ml,
|
|
6888
|
+
ai,
|
|
6668
6889
|
invokeHook,
|
|
6669
6890
|
notifyRuntimeError
|
|
6670
6891
|
}) => {
|
|
@@ -6674,13 +6895,15 @@ var executeEntryDecision = async ({
|
|
|
6674
6895
|
"beforePlaceOrder",
|
|
6675
6896
|
manifest?.hooks?.beforePlaceOrder,
|
|
6676
6897
|
{
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
runtime,
|
|
6898
|
+
ctx: hookCtx,
|
|
6899
|
+
market,
|
|
6680
6900
|
decision,
|
|
6681
|
-
|
|
6901
|
+
entry,
|
|
6902
|
+
policy,
|
|
6903
|
+
ml,
|
|
6904
|
+
ai
|
|
6682
6905
|
},
|
|
6683
|
-
{ decision,
|
|
6906
|
+
{ decision, entry, market }
|
|
6684
6907
|
);
|
|
6685
6908
|
try {
|
|
6686
6909
|
await runtime.beforePlaceOrder?.();
|
|
@@ -6689,7 +6912,8 @@ var executeEntryDecision = async ({
|
|
|
6689
6912
|
stage: "runtime.beforePlaceOrder",
|
|
6690
6913
|
error,
|
|
6691
6914
|
decision,
|
|
6692
|
-
|
|
6915
|
+
entry,
|
|
6916
|
+
market
|
|
6693
6917
|
});
|
|
6694
6918
|
throw error;
|
|
6695
6919
|
}
|
|
@@ -6712,13 +6936,18 @@ var executeEntryDecision = async ({
|
|
|
6712
6936
|
"afterPlaceOrder",
|
|
6713
6937
|
manifest?.hooks?.afterPlaceOrder,
|
|
6714
6938
|
{
|
|
6715
|
-
|
|
6939
|
+
ctx: hookCtx,
|
|
6940
|
+
market,
|
|
6716
6941
|
decision,
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6942
|
+
entry,
|
|
6943
|
+
policy,
|
|
6944
|
+
ml,
|
|
6945
|
+
ai,
|
|
6946
|
+
order: {
|
|
6947
|
+
result: signal
|
|
6948
|
+
}
|
|
6720
6949
|
},
|
|
6721
|
-
{ decision,
|
|
6950
|
+
{ decision, entry, market }
|
|
6722
6951
|
);
|
|
6723
6952
|
return signal;
|
|
6724
6953
|
}
|
|
@@ -6738,13 +6967,18 @@ var executeEntryDecision = async ({
|
|
|
6738
6967
|
"afterPlaceOrder",
|
|
6739
6968
|
manifest?.hooks?.afterPlaceOrder,
|
|
6740
6969
|
{
|
|
6741
|
-
|
|
6970
|
+
ctx: hookCtx,
|
|
6971
|
+
market,
|
|
6742
6972
|
decision,
|
|
6743
|
-
|
|
6744
|
-
|
|
6745
|
-
|
|
6973
|
+
entry,
|
|
6974
|
+
policy,
|
|
6975
|
+
ml,
|
|
6976
|
+
ai,
|
|
6977
|
+
order: {
|
|
6978
|
+
result: decision.code
|
|
6979
|
+
}
|
|
6746
6980
|
},
|
|
6747
|
-
{ decision,
|
|
6981
|
+
{ decision, entry, market }
|
|
6748
6982
|
);
|
|
6749
6983
|
} catch (err) {
|
|
6750
6984
|
if (signal) {
|
|
@@ -6754,7 +6988,8 @@ var executeEntryDecision = async ({
|
|
|
6754
6988
|
stage: "placeOrder",
|
|
6755
6989
|
error: err,
|
|
6756
6990
|
decision,
|
|
6757
|
-
|
|
6991
|
+
entry,
|
|
6992
|
+
market
|
|
6758
6993
|
});
|
|
6759
6994
|
import_logger5.logger.error("order error: %s %s", symbol, err);
|
|
6760
6995
|
return signal ?? "ORDER_ERROR";
|
|
@@ -6768,6 +7003,7 @@ var createStrategyRuntime = ({
|
|
|
6768
7003
|
manifest: staticManifest,
|
|
6769
7004
|
strategyDirectory
|
|
6770
7005
|
}) => {
|
|
7006
|
+
const projectRoot = getTradejsProjectCwd();
|
|
6771
7007
|
const resolveManifest = (name) => {
|
|
6772
7008
|
if (!name) {
|
|
6773
7009
|
return void 0;
|
|
@@ -6775,11 +7011,11 @@ var createStrategyRuntime = ({
|
|
|
6775
7011
|
if (staticManifest?.name === name) {
|
|
6776
7012
|
return staticManifest;
|
|
6777
7013
|
}
|
|
6778
|
-
return getStrategyManifest(name);
|
|
7014
|
+
return getStrategyManifest(name, projectRoot);
|
|
6779
7015
|
};
|
|
6780
7016
|
const loadPineScript2 = createLoadPineScript(
|
|
6781
7017
|
strategyDirectory ? import_node_path2.default.resolve(strategyDirectory) : import_node_path2.default.resolve(
|
|
6782
|
-
|
|
7018
|
+
projectRoot,
|
|
6783
7019
|
"packages",
|
|
6784
7020
|
"strategies",
|
|
6785
7021
|
"src",
|
|
@@ -6810,33 +7046,37 @@ var createStrategyRuntime = ({
|
|
|
6810
7046
|
strategyName,
|
|
6811
7047
|
userName,
|
|
6812
7048
|
symbol,
|
|
6813
|
-
config,
|
|
7049
|
+
strategyConfig: config,
|
|
6814
7050
|
env,
|
|
6815
7051
|
isConfigFromBacktest
|
|
6816
7052
|
};
|
|
7053
|
+
const getHookCtx = (name = strategyName) => buildHookCtx({
|
|
7054
|
+
...hookBase,
|
|
7055
|
+
strategyName: name
|
|
7056
|
+
});
|
|
6817
7057
|
const notifyRuntimeError = async ({
|
|
6818
7058
|
stage,
|
|
6819
7059
|
error,
|
|
6820
7060
|
decision,
|
|
6821
|
-
|
|
7061
|
+
entry,
|
|
7062
|
+
market
|
|
6822
7063
|
}) => {
|
|
6823
7064
|
const errorStrategyName = decision?.kind === "entry" ? decision.entryContext.strategy : strategyName;
|
|
6824
7065
|
const errorManifest = resolveManifest(errorStrategyName) ?? strategyManifest;
|
|
6825
|
-
const errorHookBase = {
|
|
6826
|
-
...hookBase,
|
|
6827
|
-
strategyName: errorStrategyName
|
|
6828
|
-
};
|
|
6829
7066
|
const onRuntimeError = errorManifest?.hooks?.onRuntimeError;
|
|
6830
7067
|
if (!onRuntimeError) {
|
|
6831
7068
|
return;
|
|
6832
7069
|
}
|
|
6833
7070
|
try {
|
|
6834
7071
|
await onRuntimeError({
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
error,
|
|
7072
|
+
ctx: getHookCtx(errorStrategyName),
|
|
7073
|
+
market,
|
|
6838
7074
|
decision,
|
|
6839
|
-
|
|
7075
|
+
entry,
|
|
7076
|
+
error: {
|
|
7077
|
+
stage,
|
|
7078
|
+
cause: error
|
|
7079
|
+
}
|
|
6840
7080
|
});
|
|
6841
7081
|
} catch (hookError) {
|
|
6842
7082
|
import_logger5.logger.error(
|
|
@@ -6863,7 +7103,8 @@ var createStrategyRuntime = ({
|
|
|
6863
7103
|
stage,
|
|
6864
7104
|
error,
|
|
6865
7105
|
decision: errorContext.decision,
|
|
6866
|
-
|
|
7106
|
+
entry: errorContext.entry,
|
|
7107
|
+
market: errorContext.market
|
|
6867
7108
|
});
|
|
6868
7109
|
return void 0;
|
|
6869
7110
|
}
|
|
@@ -6874,7 +7115,8 @@ var createStrategyRuntime = ({
|
|
|
6874
7115
|
btcData,
|
|
6875
7116
|
btcBinanceData,
|
|
6876
7117
|
btcCoinbaseData,
|
|
6877
|
-
periods: (0, import_strategies.buildDefaultIndicatorPeriods)(config)
|
|
7118
|
+
periods: (0, import_strategies.buildDefaultIndicatorPeriods)(config),
|
|
7119
|
+
pluginRegistryScope: projectRoot
|
|
6878
7120
|
});
|
|
6879
7121
|
const strategyApi = (0, import_strategies.createStrategyAPI)({
|
|
6880
7122
|
strategy: strategyName,
|
|
@@ -6901,39 +7143,45 @@ var createStrategyRuntime = ({
|
|
|
6901
7143
|
indicatorsState
|
|
6902
7144
|
});
|
|
6903
7145
|
await invokeHook("onInit", strategyManifest?.hooks?.onInit, {
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
7146
|
+
ctx: getHookCtx(),
|
|
7147
|
+
market: {
|
|
7148
|
+
data,
|
|
7149
|
+
btcData
|
|
7150
|
+
}
|
|
6907
7151
|
});
|
|
6908
7152
|
return async (candle, btcCandle) => {
|
|
6909
7153
|
data.push(candle);
|
|
6910
7154
|
btcData.push(btcCandle);
|
|
6911
7155
|
indicatorsState.setCurrentBar(candle, btcCandle);
|
|
7156
|
+
const market = {
|
|
7157
|
+
candle,
|
|
7158
|
+
btcCandle
|
|
7159
|
+
};
|
|
6912
7160
|
const decision = await core(candle, btcCandle);
|
|
6913
7161
|
const decisionStrategyName = decision.kind === "entry" ? decision.entryContext.strategy : strategyName;
|
|
6914
7162
|
const decisionManifest = resolveManifest(decisionStrategyName) ?? strategyManifest;
|
|
6915
|
-
const
|
|
6916
|
-
...hookBase,
|
|
6917
|
-
strategyName: decisionStrategyName
|
|
6918
|
-
};
|
|
7163
|
+
const decisionHookCtx = getHookCtx(decisionStrategyName);
|
|
6919
7164
|
await invokeHook(
|
|
6920
7165
|
"afterCoreDecision",
|
|
6921
7166
|
decisionManifest?.hooks?.afterCoreDecision,
|
|
6922
7167
|
{
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
btcCandle
|
|
7168
|
+
ctx: decisionHookCtx,
|
|
7169
|
+
market,
|
|
7170
|
+
decision
|
|
6927
7171
|
},
|
|
6928
|
-
{ decision }
|
|
7172
|
+
{ decision, market }
|
|
6929
7173
|
);
|
|
6930
7174
|
if (decision.kind === "skip") {
|
|
6931
|
-
await invokeHook(
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
7175
|
+
await invokeHook(
|
|
7176
|
+
"onSkip",
|
|
7177
|
+
decisionManifest?.hooks?.onSkip,
|
|
7178
|
+
{
|
|
7179
|
+
ctx: decisionHookCtx,
|
|
7180
|
+
market,
|
|
7181
|
+
decision
|
|
7182
|
+
},
|
|
7183
|
+
{ decision, market }
|
|
7184
|
+
);
|
|
6937
7185
|
return decision.code;
|
|
6938
7186
|
}
|
|
6939
7187
|
const makeOrdersEnabled = typeof config.MAKE_ORDERS === "boolean" ? config.MAKE_ORDERS : true;
|
|
@@ -6945,10 +7193,11 @@ var createStrategyRuntime = ({
|
|
|
6945
7193
|
"beforeClosePosition",
|
|
6946
7194
|
decisionManifest?.hooks?.beforeClosePosition,
|
|
6947
7195
|
{
|
|
6948
|
-
|
|
7196
|
+
ctx: decisionHookCtx,
|
|
7197
|
+
market,
|
|
6949
7198
|
decision
|
|
6950
7199
|
},
|
|
6951
|
-
{ decision }
|
|
7200
|
+
{ decision, market }
|
|
6952
7201
|
);
|
|
6953
7202
|
if (closeGate?.allow === false) {
|
|
6954
7203
|
return closeGate.reason ? `CLOSE_BLOCKED_BY_HOOK:${closeGate.reason}` : "CLOSE_BLOCKED_BY_HOOK";
|
|
@@ -6957,11 +7206,18 @@ var createStrategyRuntime = ({
|
|
|
6957
7206
|
connector,
|
|
6958
7207
|
symbol,
|
|
6959
7208
|
decision,
|
|
6960
|
-
|
|
7209
|
+
market,
|
|
7210
|
+
onRuntimeError: async ({
|
|
7211
|
+
stage,
|
|
7212
|
+
error,
|
|
7213
|
+
decision: exitDecision,
|
|
7214
|
+
market: errorMarket
|
|
7215
|
+
}) => {
|
|
6961
7216
|
await notifyRuntimeError({
|
|
6962
7217
|
stage,
|
|
6963
7218
|
error,
|
|
6964
|
-
decision: exitDecision
|
|
7219
|
+
decision: exitDecision,
|
|
7220
|
+
market: errorMarket
|
|
6965
7221
|
});
|
|
6966
7222
|
}
|
|
6967
7223
|
});
|
|
@@ -6972,6 +7228,11 @@ var createStrategyRuntime = ({
|
|
|
6972
7228
|
manifest: decisionManifest
|
|
6973
7229
|
});
|
|
6974
7230
|
const signal = decision.signal;
|
|
7231
|
+
const entry = buildHookEntry({
|
|
7232
|
+
decision,
|
|
7233
|
+
runtime
|
|
7234
|
+
});
|
|
7235
|
+
let ml;
|
|
6975
7236
|
if (signal) {
|
|
6976
7237
|
try {
|
|
6977
7238
|
await enrichSignalWithMl({
|
|
@@ -6984,23 +7245,31 @@ var createStrategyRuntime = ({
|
|
|
6984
7245
|
stage: "enrichSignalWithMl",
|
|
6985
7246
|
error,
|
|
6986
7247
|
decision,
|
|
6987
|
-
|
|
7248
|
+
entry,
|
|
7249
|
+
market
|
|
6988
7250
|
});
|
|
6989
7251
|
throw error;
|
|
6990
7252
|
}
|
|
7253
|
+
ml = buildMlHookContext({
|
|
7254
|
+
signal,
|
|
7255
|
+
env,
|
|
7256
|
+
ml: runtime.ml
|
|
7257
|
+
});
|
|
6991
7258
|
await invokeHook(
|
|
6992
7259
|
"afterEnrichMl",
|
|
6993
7260
|
decisionManifest?.hooks?.afterEnrichMl,
|
|
6994
7261
|
{
|
|
6995
|
-
|
|
7262
|
+
ctx: decisionHookCtx,
|
|
7263
|
+
market,
|
|
6996
7264
|
decision,
|
|
6997
|
-
|
|
6998
|
-
|
|
7265
|
+
entry,
|
|
7266
|
+
ml
|
|
6999
7267
|
},
|
|
7000
|
-
{ decision,
|
|
7268
|
+
{ decision, entry, market }
|
|
7001
7269
|
);
|
|
7002
7270
|
}
|
|
7003
7271
|
let quality;
|
|
7272
|
+
let ai;
|
|
7004
7273
|
if (signal) {
|
|
7005
7274
|
try {
|
|
7006
7275
|
quality = await enrichSignalWithAi({
|
|
@@ -7015,24 +7284,36 @@ var createStrategyRuntime = ({
|
|
|
7015
7284
|
stage: "enrichSignalWithAi",
|
|
7016
7285
|
error,
|
|
7017
7286
|
decision,
|
|
7018
|
-
|
|
7287
|
+
entry,
|
|
7288
|
+
market
|
|
7019
7289
|
});
|
|
7020
7290
|
throw error;
|
|
7021
7291
|
}
|
|
7292
|
+
ai = buildAiHookContext({
|
|
7293
|
+
env,
|
|
7294
|
+
ai: runtime.ai,
|
|
7295
|
+
quality
|
|
7296
|
+
});
|
|
7022
7297
|
await invokeHook(
|
|
7023
7298
|
"afterEnrichAi",
|
|
7024
7299
|
decisionManifest?.hooks?.afterEnrichAi,
|
|
7025
7300
|
{
|
|
7026
|
-
|
|
7301
|
+
ctx: decisionHookCtx,
|
|
7302
|
+
market,
|
|
7027
7303
|
decision,
|
|
7028
|
-
|
|
7029
|
-
signal,
|
|
7030
|
-
|
|
7304
|
+
entry,
|
|
7305
|
+
ml: ml ?? buildMlHookContext({ signal, env, ml: runtime.ml }),
|
|
7306
|
+
ai
|
|
7031
7307
|
},
|
|
7032
|
-
{ decision,
|
|
7308
|
+
{ decision, entry, market }
|
|
7033
7309
|
);
|
|
7034
7310
|
}
|
|
7035
7311
|
const minAiQuality = runtime.ai?.minQuality ?? 4;
|
|
7312
|
+
const policy = buildHookPolicy({
|
|
7313
|
+
quality,
|
|
7314
|
+
makeOrdersEnabled,
|
|
7315
|
+
minAiQuality
|
|
7316
|
+
});
|
|
7036
7317
|
const shouldMakeOrder = shouldExecuteEntryDecision({
|
|
7037
7318
|
makeOrdersEnabled,
|
|
7038
7319
|
env,
|
|
@@ -7056,15 +7337,15 @@ var createStrategyRuntime = ({
|
|
|
7056
7337
|
"beforeEntryGate",
|
|
7057
7338
|
decisionManifest?.hooks?.beforeEntryGate,
|
|
7058
7339
|
{
|
|
7059
|
-
|
|
7340
|
+
ctx: decisionHookCtx,
|
|
7341
|
+
market,
|
|
7060
7342
|
decision,
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
|
|
7065
|
-
minAiQuality
|
|
7343
|
+
entry,
|
|
7344
|
+
policy,
|
|
7345
|
+
ml,
|
|
7346
|
+
ai
|
|
7066
7347
|
},
|
|
7067
|
-
{ decision,
|
|
7348
|
+
{ decision, entry, market }
|
|
7068
7349
|
);
|
|
7069
7350
|
if (entryGate?.allow === false) {
|
|
7070
7351
|
const skipReason = entryGate.reason ? `HOOK_BEFORE_ENTRY_GATE:${entryGate.reason}` : "HOOK_BEFORE_ENTRY_GATE";
|
|
@@ -7080,7 +7361,12 @@ var createStrategyRuntime = ({
|
|
|
7080
7361
|
decision,
|
|
7081
7362
|
runtime,
|
|
7082
7363
|
manifest: decisionManifest,
|
|
7083
|
-
|
|
7364
|
+
hookCtx: decisionHookCtx,
|
|
7365
|
+
market,
|
|
7366
|
+
entry,
|
|
7367
|
+
policy,
|
|
7368
|
+
ml,
|
|
7369
|
+
ai,
|
|
7084
7370
|
invokeHook,
|
|
7085
7371
|
notifyRuntimeError
|
|
7086
7372
|
});
|
|
@@ -7092,13 +7378,13 @@ var createStrategyRuntime = ({
|
|
|
7092
7378
|
var createCloseOppositeBeforePlaceOrderHook = ({
|
|
7093
7379
|
isEnabled
|
|
7094
7380
|
}) => {
|
|
7095
|
-
return async ({
|
|
7096
|
-
if (!isEnabled(
|
|
7381
|
+
return async ({ ctx, entry }) => {
|
|
7382
|
+
if (!isEnabled(ctx.strategyConfig)) {
|
|
7097
7383
|
return;
|
|
7098
7384
|
}
|
|
7099
7385
|
await closeOppositePositionsBeforeOpen({
|
|
7100
|
-
connector,
|
|
7101
|
-
entryContext
|
|
7386
|
+
connector: ctx.connector,
|
|
7387
|
+
entryContext: entry.context
|
|
7102
7388
|
});
|
|
7103
7389
|
};
|
|
7104
7390
|
};
|