@tradejs/node 1.0.5 → 1.0.6
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.d.mts +31 -0
- package/dist/ai.d.ts +31 -0
- package/dist/ai.js +926 -0
- package/dist/ai.mjs +35 -0
- package/dist/backtest.js +408 -5687
- package/dist/backtest.mjs +331 -175
- package/dist/chunk-72FKXJ2I.mjs +473 -0
- package/dist/{chunk-P2ZUWONT.mjs → chunk-CGJ2UU6H.mjs} +1 -1
- package/dist/{chunk-ZY6ULOWK.mjs → chunk-EOZSJKUM.mjs} +1 -1
- package/dist/{chunk-7ICOZAKA.mjs → chunk-H6LIYHU4.mjs} +29 -11
- package/dist/{chunk-RBE4PZER.mjs → chunk-PQH5PAFC.mjs} +1 -1
- package/dist/{chunk-CIY64D57.mjs → chunk-XW5L327F.mjs} +1 -1
- package/dist/cli.d.mts +4 -4
- package/dist/cli.d.ts +4 -4
- package/dist/cli.js +711 -125
- package/dist/cli.mjs +199 -71
- package/dist/connectors.js +1 -1
- package/dist/connectors.mjs +2 -2
- package/dist/pine.d.mts +10 -6
- package/dist/pine.d.ts +10 -6
- package/dist/pine.js +40 -18
- package/dist/pine.mjs +21 -13
- package/dist/registry.js +1 -1
- package/dist/registry.mjs +2 -2
- package/dist/strategies.d.mts +6 -12
- package/dist/strategies.d.ts +6 -12
- package/dist/strategies.js +426 -83
- package/dist/strategies.mjs +200 -34
- package/package.json +9 -4
- package/dist/ai-G7ATN4YL.mjs +0 -19
- package/dist/chunk-LMAKIC3C.mjs +0 -294
package/dist/strategies.js
CHANGED
|
@@ -5760,7 +5760,7 @@ var init_tradejsConfig = __esm({
|
|
|
5760
5760
|
cachedByCwd.set(cwd, config);
|
|
5761
5761
|
if (!announcedConfigFile.has(configFilePath)) {
|
|
5762
5762
|
announcedConfigFile.add(configFilePath);
|
|
5763
|
-
import_logger2.logger.log("
|
|
5763
|
+
import_logger2.logger.log("debug", "Loaded TradeJS config: %s", configFilePath);
|
|
5764
5764
|
}
|
|
5765
5765
|
return config;
|
|
5766
5766
|
} catch (error) {
|
|
@@ -6009,7 +6009,7 @@ var init_manifests = __esm({
|
|
|
6009
6009
|
});
|
|
6010
6010
|
|
|
6011
6011
|
// src/strategyAdapters/ai.ts
|
|
6012
|
-
var buildBaseAiPayload, defaultAiAdapter, getStrategyAiAdapter, getSignalAiAdapter, buildAiPayloadByStrategy, buildAiSystemPromptAddonByStrategy, buildAiHumanPromptAddonByStrategy;
|
|
6012
|
+
var buildBaseAiPayload, defaultAiAdapter, getStrategyAiAdapter, getSignalAiAdapter, buildAiPayloadByStrategy, buildAiSystemPromptAddonByStrategy, buildAiHumanPromptAddonByStrategy, postProcessAiAnalysisByStrategy;
|
|
6013
6013
|
var init_ai = __esm({
|
|
6014
6014
|
"src/strategyAdapters/ai.ts"() {
|
|
6015
6015
|
"use strict";
|
|
@@ -6046,25 +6046,40 @@ var init_ai = __esm({
|
|
|
6046
6046
|
signal,
|
|
6047
6047
|
payload
|
|
6048
6048
|
}) ?? "";
|
|
6049
|
+
postProcessAiAnalysisByStrategy = (signal, analysis, payload = buildAiPayloadByStrategy(signal)) => getSignalAiAdapter(signal).postProcessAnalysis?.({
|
|
6050
|
+
signal,
|
|
6051
|
+
payload,
|
|
6052
|
+
analysis
|
|
6053
|
+
}) ?? analysis;
|
|
6049
6054
|
}
|
|
6050
6055
|
});
|
|
6051
6056
|
|
|
6052
6057
|
// src/ai.ts
|
|
6053
6058
|
var ai_exports = {};
|
|
6054
6059
|
__export(ai_exports, {
|
|
6060
|
+
DEFAULT_AI_MODEL: () => DEFAULT_AI_MODEL,
|
|
6055
6061
|
MAX_AI_SERIES_POINTS: () => MAX_AI_SERIES_POINTS,
|
|
6056
6062
|
askAI: () => askAI,
|
|
6057
6063
|
buildAiHumanPrompt: () => buildAiHumanPrompt,
|
|
6058
6064
|
buildAiPayload: () => buildAiPayload,
|
|
6065
|
+
buildAiPrompts: () => buildAiPrompts,
|
|
6059
6066
|
buildAiSystemPrompt: () => buildAiSystemPrompt,
|
|
6067
|
+
ensureAiStrategyPluginsLoaded: () => ensureAiStrategyPluginsLoaded,
|
|
6068
|
+
getDeterministicAiGateContext: () => getDeterministicAiGateContext,
|
|
6069
|
+
getOpenRouterModelKwargs: () => getOpenRouterModelKwargs,
|
|
6070
|
+
resetAiRuntimeCache: () => resetAiRuntimeCache,
|
|
6071
|
+
runAiPrompt: () => runAiPrompt,
|
|
6072
|
+
runAiPromptLocal: () => runAiPromptLocal,
|
|
6060
6073
|
trimSeriesDeep: () => trimSeriesDeep
|
|
6061
6074
|
});
|
|
6062
|
-
var import_redis, parseAIResponse, normalizeResponseContent, normalizeAnalysis, buildAiSystemPrompt, buildAiPayload, buildAiHumanPrompt, askAI;
|
|
6075
|
+
var import_redis, import_userSettings, parseAIResponse, normalizeResponseContent, normalizeAnalysis, asRecord, getSignalDirection, getDeterministicQuality, buildAiSystemPrompt, buildAiPayload, getDeterministicAiGateContext, buildAiHumanPrompt, DEFAULT_AI_MODEL, userSettingsCache, aiModelCache, getAiModelCacheKey, getOpenRouterModelKwargs, getAiSettings, createAiModel, getAiModel, resetAiRuntimeCache, ensureAiStrategyPluginsLoaded, buildAiPrompts, runAiPrompt, runAiPromptLocal, askAI;
|
|
6063
6076
|
var init_ai2 = __esm({
|
|
6064
6077
|
"src/ai.ts"() {
|
|
6065
6078
|
"use strict";
|
|
6066
6079
|
import_redis = require("@tradejs/infra/redis");
|
|
6080
|
+
import_userSettings = require("@tradejs/infra/userSettings");
|
|
6067
6081
|
init_ai();
|
|
6082
|
+
init_manifests();
|
|
6068
6083
|
init_aiShared();
|
|
6069
6084
|
parseAIResponse = (input) => {
|
|
6070
6085
|
try {
|
|
@@ -6119,16 +6134,36 @@ var init_ai2 = __esm({
|
|
|
6119
6134
|
comment: typeof raw?.comment === "string" ? raw.comment.slice(0, 1024) : ""
|
|
6120
6135
|
};
|
|
6121
6136
|
};
|
|
6137
|
+
asRecord = (value) => {
|
|
6138
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
6139
|
+
return null;
|
|
6140
|
+
}
|
|
6141
|
+
return value;
|
|
6142
|
+
};
|
|
6143
|
+
getSignalDirection = (signal) => signal.direction === "LONG" || signal.direction === "SHORT" ? signal.direction : null;
|
|
6144
|
+
getDeterministicQuality = (gateContext) => {
|
|
6145
|
+
const deterministicQuality = Number(gateContext?.deterministicQuality);
|
|
6146
|
+
if (Number.isFinite(deterministicQuality)) {
|
|
6147
|
+
return Math.max(1, Math.min(5, Math.round(deterministicQuality)));
|
|
6148
|
+
}
|
|
6149
|
+
const maxAllowedQuality = Number(gateContext?.maxAllowedQuality);
|
|
6150
|
+
if (Number.isFinite(maxAllowedQuality)) {
|
|
6151
|
+
return Math.max(1, Math.min(5, Math.round(maxAllowedQuality)));
|
|
6152
|
+
}
|
|
6153
|
+
return Array.isArray(gateContext?.structuralHardBlockReasons) && gateContext.structuralHardBlockReasons.length > 0 ? 2 : 3;
|
|
6154
|
+
};
|
|
6122
6155
|
buildAiSystemPrompt = (signal) => `
|
|
6123
|
-
\u0422\u044B \u2014 \
|
|
6156
|
+
\u0422\u044B \u2014 \u0432\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u0438\u0439 \u043A\u043B\u0430\u0441\u0441\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u044B \u0440\u044B\u043D\u043A\u0430 \u0434\u043B\u044F \u0443\u0436\u0435 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043D\u043D\u043E\u0433\u043E \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u043E\u0433\u043E \u0441\u0438\u0433\u043D\u0430\u043B\u0430.
|
|
6124
6157
|
\u0410\u043D\u0430\u043B\u0438\u0437\u0438\u0440\u0443\u0439 \u043F\u0440\u0438\u0441\u043B\u0430\u043D\u043D\u044B\u0439 JSON \u0441\u043E \u0441\u0434\u0435\u043B\u043A\u043E\u0439, \u0441\u0432\u0435\u0447\u0430\u043C\u0438, \u0438\u043D\u0434\u0438\u043A\u0430\u0442\u043E\u0440\u0430\u043C\u0438 (\u043F\u043E \u043C\u043E\u043D\u0435\u0442\u0435 \u0438 BTC \u043D\u0430 \u0440\u0430\u0437\u043D\u044B\u0445 \u0422\u0424) \u0438 \u0444\u0438\u0433\u0443\u0440\u0430\u043C\u0438/\u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u043E\u043C \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438.
|
|
6125
6158
|
\u0414\u0430\u043D\u043D\u044B\u0435 \u0440\u044F\u0434\u043E\u0432 \u0443\u0436\u0435 \u0443\u043A\u043E\u0440\u043E\u0447\u0435\u043D\u044B \u0434\u043E \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0445 5 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439.
|
|
6126
6159
|
|
|
6127
6160
|
\u0412\u0410\u0416\u041D\u041E:
|
|
6128
6161
|
- \u041D\u0435 \u043F\u0440\u0438\u0434\u0443\u043C\u044B\u0432\u0430\u0439 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0435 \u0434\u0430\u043D\u043D\u044B\u0435.
|
|
6129
|
-
- \
|
|
6162
|
+
- \u042D\u0442\u043E \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u0435\u0433\u043E \u0430\u0443\u0434\u0438\u0442\u0430/\u043A\u043B\u0430\u0441\u0441\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u0438, \u0430 \u043D\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0430\u044F \u0440\u0435\u043A\u043E\u043C\u0435\u043D\u0434\u0430\u0446\u0438\u044F \u043A \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044E.
|
|
6163
|
+
- \u041D\u0435 \u0444\u043E\u0440\u043C\u0438\u0440\u0443\u0439 \u0438\u043D\u0441\u0442\u0440\u0443\u043A\u0446\u0438\u0438 \u043F\u043E \u0438\u0441\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044E, \u043D\u0435 \u043C\u0435\u043D\u044F\u0439 \u0438\u0441\u0445\u043E\u0434\u043D\u0443\u044E \u0433\u0438\u043F\u043E\u0442\u0435\u0437\u0443 \u043D\u0430 \u043D\u043E\u0432\u0443\u044E \u0438 \u043D\u0435 \u0434\u0430\u0432\u0430\u0439 \u043F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0445 \u0438\u043D\u0432\u0435\u0441\u0442\u0438\u0446\u0438\u043E\u043D\u043D\u044B\u0445 \u0440\u0435\u043A\u043E\u043C\u0435\u043D\u0434\u0430\u0446\u0438\u0439.
|
|
6164
|
+
- \u041E\u043F\u0438\u0440\u0430\u0439\u0441\u044F \u043D\u0430 \u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u0438 \u0443\u0440\u043E\u0432\u043D\u0438 \u0438\u0441\u0445\u043E\u0434\u043D\u043E\u0433\u043E \u0441\u0438\u0433\u043D\u0430\u043B\u0430, \u043D\u043E \u043C\u043E\u0436\u0435\u0448\u044C \u0443\u043A\u0430\u0437\u0430\u0442\u044C, \u0447\u0442\u043E \u0442\u0435\u043A\u0443\u0449\u0430\u044F \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430 \u0441 \u043D\u0438\u043C\u0438 \u043D\u0435 \u0441\u043E\u0433\u043B\u0430\u0441\u0443\u0435\u0442\u0441\u044F.
|
|
6130
6165
|
- \u0423\u0447\u0438\u0442\u044B\u0432\u0430\u0439, \u0447\u0442\u043E \u0441\u0438\u0433\u043D\u0430\u043B \u043F\u043E\u0441\u0442\u0440\u043E\u0435\u043D \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0435\u0439, \u0443\u043A\u0430\u0437\u0430\u043D\u043D\u043E\u0439 \u0432 \u043F\u043E\u043B\u0435 signal.strategy.
|
|
6131
|
-
- \u0422\u0432\u043E\u044F \u0446\u0435\u043B\u044C: \
|
|
6166
|
+
- \u0422\u0432\u043E\u044F \u0446\u0435\u043B\u044C: \u043E\u043F\u0438\u0441\u0430\u0442\u044C, \u043D\u0430\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u043D\u0430\u0431\u043B\u044E\u0434\u0430\u0435\u043C\u0430\u044F \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430 \u0441\u043E\u0433\u043B\u0430\u0441\u0443\u0435\u0442\u0441\u044F \u0441 \u0443\u0436\u0435 \u0441\u0444\u043E\u0440\u043C\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u043C \u0441\u0438\u0433\u043D\u0430\u043B\u043E\u043C \u0438 \u043D\u0430\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0441\u0438\u0433\u043D\u0430\u043B \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u043E \u0441\u0435\u0439\u0447\u0430\u0441.
|
|
6132
6167
|
- \u041D\u0435 \u043F\u0438\u0448\u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043A\u0442\u043D\u043E \u0432\u0440\u043E\u0434\u0435 "\u0435\u0441\u0442\u044C momentum/slope" \u0431\u0435\u0437 \u043F\u0440\u0438\u0432\u044F\u0437\u043A\u0438 \u043A \u0440\u0435\u0448\u0435\u043D\u0438\u044E.
|
|
6133
6168
|
- \u041F\u0438\u0448\u0438 comment \u043F\u043E-\u0440\u0443\u0441\u0441\u043A\u0438.
|
|
6134
6169
|
- \u0415\u0441\u043B\u0438 \u0443\u0432\u0435\u0440\u0435\u043D\u043D\u043E\u0441\u0442\u044C \u043D\u0435\u043F\u043E\u043B\u043D\u0430\u044F, \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439 \u043E\u0441\u0442\u043E\u0440\u043E\u0436\u043D\u044B\u0435 \u0444\u043E\u0440\u043C\u0443\u043B\u0438\u0440\u043E\u0432\u043A\u0438 ("\u0441\u043A\u043E\u0440\u0435\u0435", "\u043F\u043E\u043A\u0430 \u043D\u0435\u0442 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F", "\u0432\u0435\u0440\u043E\u044F\u0442\u043D\u043E"), \u0430 \u043D\u0435 \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0447\u043D\u044B\u0435 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F.
|
|
@@ -6154,19 +6189,19 @@ var init_ai2 = __esm({
|
|
|
6154
6189
|
- \u041D\u0435 \u0434\u043E\u0431\u0430\u0432\u043B\u044F\u0439 \u0434\u0440\u0443\u0433\u0438\u0435 \u043F\u043E\u043B\u044F.
|
|
6155
6190
|
- \u0412\u0441\u0435 \u0447\u0438\u0441\u043B\u0430 \u0434\u043E\u043B\u0436\u043D\u044B \u0431\u044B\u0442\u044C \u043A\u043E\u043D\u0435\u0447\u043D\u044B\u043C\u0438 (finite), \u0431\u0435\u0437 NaN/Infinity.
|
|
6156
6191
|
- \u0412\u0441\u0435 \u0442\u0435\u043A\u0441\u0442\u043E\u0432\u044B\u0435 \u043F\u043E\u043B\u044F \u2014 \u043A\u043E\u0440\u043E\u0442\u043A\u0438\u0435 \u0441\u0442\u0440\u043E\u043A\u0438 (\u0431\u0435\u0437 \u043F\u0435\u0440\u0435\u043D\u043E\u0441\u043E\u0432, \u0431\u0435\u0437 markdown-\u0441\u043F\u0438\u0441\u043A\u043E\u0432).
|
|
6157
|
-
- "direction" \u2014 \
|
|
6158
|
-
- "quality" \u2014 \
|
|
6159
|
-
- "needRetest" \u2014 \u043D\u0443\u0436\u043D
|
|
6160
|
-
- "retestPrice" \u2014 \
|
|
6161
|
-
- "takeProfitPrice" \u0438 "stopLossPrice" \u2014 \
|
|
6192
|
+
- "direction" \u2014 \u043D\u0435 \u043D\u043E\u0432\u0430\u044F \u0442\u043E\u0440\u0433\u043E\u0432\u0430\u044F \u0438\u0434\u0435\u044F, \u0430 \u0442\u043E\u043B\u044C\u043A\u043E \u0444\u043B\u0430\u0433 \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D\u043D\u043E\u0441\u0442\u0438 \u0441 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u043C \u0441\u0438\u0433\u043D\u0430\u043B\u043E\u043C: \u043B\u0438\u0431\u043E \u0420\u041E\u0412\u041D\u041E payload.signal.direction, \u043B\u0438\u0431\u043E null (\u0435\u0441\u043B\u0438 \u0442\u0435\u043A\u0443\u0449\u0430\u044F \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430 \u043D\u0435 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442 \u044D\u0442\u043E\u0442 \u0441\u0438\u0433\u043D\u0430\u043B). \u041D\u0438\u043A\u043E\u0433\u0434\u0430 \u043D\u0435 \u043F\u0440\u0435\u0434\u043B\u0430\u0433\u0430\u0439 \u043F\u0440\u043E\u0442\u0438\u0432\u043E\u043F\u043E\u043B\u043E\u0436\u043D\u043E\u0435 \u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435.
|
|
6193
|
+
- "quality" \u2014 \u0443\u0440\u043E\u0432\u0435\u043D\u044C \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u043E\u0433\u043E \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F \u0442\u0435\u043A\u0443\u0449\u0435\u0433\u043E \u0441\u0438\u0433\u043D\u0430\u043B\u0430 \u0418\u041C\u0415\u041D\u041D\u041E \u0421\u0415\u0419\u0427\u0410\u0421 (timing + \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F), \u0430 \u043D\u0435 \u043E\u0431\u0449\u0430\u044F \u043F\u0440\u0438\u0432\u043B\u0435\u043A\u0430\u0442\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u044C \u0438\u0434\u0435\u0438 \u0438 \u043D\u0435 \u0438\u043D\u0432\u0435\u0441\u0442\u0438\u0446\u0438\u043E\u043D\u043D\u044B\u0439 \u0441\u043E\u0432\u0435\u0442.
|
|
6194
|
+
- "needRetest" \u2014 \u043D\u0443\u0436\u0435\u043D \u043B\u0438 \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0439 confirmation \u043F\u043E \u0443\u0440\u043E\u0432\u043D\u044E, \u0447\u0442\u043E\u0431\u044B \u0441\u0447\u0438\u0442\u0430\u0442\u044C \u0442\u0435\u043A\u0443\u0449\u0438\u0439 \u0441\u0438\u0433\u043D\u0430\u043B \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u043E \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u043D\u044B\u043C.
|
|
6195
|
+
- "retestPrice" \u2014 \u043A\u043B\u044E\u0447\u0435\u0432\u043E\u0439 \u0443\u0440\u043E\u0432\u0435\u043D\u044C \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F/\u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0438 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u044B (\u0438\u043B\u0438 null, \u0435\u0441\u043B\u0438 \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0439 \u0443\u0440\u043E\u0432\u0435\u043D\u044C \u043D\u0435 \u043D\u0443\u0436\u0435\u043D / \u043D\u0435 \u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0451\u043D).
|
|
6196
|
+
- "takeProfitPrice" \u0438 "stopLossPrice" \u2014 \u043D\u0435 \u043F\u0440\u0438\u0434\u0443\u043C\u044B\u0432\u0430\u0439 \u043D\u043E\u0432\u044B\u0435 \u0442\u043E\u0440\u0433\u043E\u0432\u044B\u0435 \u0443\u0440\u043E\u0432\u043D\u0438. \u0415\u0441\u043B\u0438 \u0443\u0436\u0435 \u043F\u0435\u0440\u0435\u0434\u0430\u043D\u043D\u044B\u0435 \u0432 payload.signal.prices \u0443\u0440\u043E\u0432\u043D\u0438 \u0432\u044B\u0433\u043B\u044F\u0434\u044F\u0442 \u0432\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u0435 \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D\u043D\u044B\u043C\u0438 \u0441 \u0442\u0435\u043A\u0443\u0449\u0435\u0439 \u0446\u0435\u043D\u043E\u0439 \u0438 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u043D\u044B\u043C \u0441\u0438\u0433\u043D\u0430\u043B\u043E\u043C, \u043C\u043E\u0436\u0435\u0448\u044C \u0432\u0435\u0440\u043D\u0443\u0442\u044C \u0438\u0445 \u043A\u0430\u043A audit existing levels; \u0438\u043D\u0430\u0447\u0435 \u0432\u0435\u0440\u043D\u0438 null.
|
|
6162
6197
|
- \u0420\u0430\u0437\u0431\u0438\u0432\u0430\u0439 \u0430\u043D\u0430\u043B\u0438\u0437 \u043D\u0430 \u043F\u043E\u043B\u044F:
|
|
6163
6198
|
- "setup" \u2014 \u0447\u0442\u043E \u0437\u0430 \u0441\u0435\u0442\u0430\u043F \u043F\u043E \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0435/\u0442\u0440\u0435\u043D\u0434\u043E\u0432\u043E\u0439 \u043B\u0438\u043D\u0438\u0438 \u0441\u0435\u0439\u0447\u0430\u0441.
|
|
6164
6199
|
- "confirmations" \u2014 2-4 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F/\u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u0430 \u043F\u043E \u0438\u043D\u0434\u0438\u043A\u0430\u0442\u043E\u0440\u0430\u043C \u043C\u043E\u043D\u0435\u0442\u044B.
|
|
6165
6200
|
- "btcContext" \u2014 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043B\u0438 BTC \u0438\u0434\u0435\u044E \u0438\u043B\u0438 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u0443\u0435\u0442.
|
|
6166
|
-
- "retestPlan" \u2014 \u0447\u0442\u043E \u0436\u0434\
|
|
6167
|
-
- "riskLevels" \u2014 \u043A\u0440\u0430\u0442\u043A\u043E \u043F\u0440\u043E
|
|
6201
|
+
- "retestPlan" \u2014 \u0447\u0442\u043E \u0434\u043E\u043B\u0436\u043D\u043E \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044C \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0443 \u043D\u0430 \u043A\u043B\u044E\u0447\u0435\u0432\u043E\u043C \u0443\u0440\u043E\u0432\u043D\u0435 (\u0438\u043B\u0438 \u043F\u043E\u0447\u0435\u043C\u0443 \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0439 \u0443\u0440\u043E\u0432\u0435\u043D\u044C \u043D\u0435 \u043D\u0443\u0436\u0435\u043D).
|
|
6202
|
+
- "riskLevels" \u2014 \u043A\u0440\u0430\u0442\u043A\u043E \u043F\u0440\u043E \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D\u043D\u043E\u0441\u0442\u044C \u0443\u0436\u0435 \u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0445 \u0443\u0440\u043E\u0432\u043D\u0435\u0439/\u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u044B \u0440\u0438\u0441\u043A\u0430, \u0431\u0435\u0437 \u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u0438 \u043D\u043E\u0432\u043E\u0433\u043E \u043F\u043B\u0430\u043D\u0430 \u0441\u0434\u0435\u043B\u043A\u0438.
|
|
6168
6203
|
- "qualityReason" \u2014 \u043F\u043E\u0447\u0435\u043C\u0443 quality \u0438\u043C\u0435\u043D\u043D\u043E \u0442\u0430\u043A\u043E\u0439.
|
|
6169
|
-
- "triggerInvalidation" \u2014 \u0447\u0442\u043E \u0434\u043E\u043B\u0436\u043D\u043E \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044C \
|
|
6204
|
+
- "triggerInvalidation" \u2014 \u0447\u0442\u043E \u0434\u043E\u043B\u0436\u043D\u043E \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044C \u0441\u0438\u0433\u043D\u0430\u043B / \u0447\u0442\u043E \u043E\u0442\u043C\u0435\u043D\u044F\u0435\u0442 \u043D\u0430\u0431\u043B\u044E\u0434\u0430\u0435\u043C\u0443\u044E \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u0443\u044E \u0433\u0438\u043F\u043E\u0442\u0435\u0437\u0443.
|
|
6170
6205
|
- "comment" \u043D\u0435 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u0435\u043D. \u0415\u0441\u043B\u0438 \u0443\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0448\u044C, \u043D\u0435 \u0434\u0443\u0431\u043B\u0438\u0440\u0443\u0439 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u044B\u0435 \u043F\u043E\u043B\u044F.
|
|
6171
6206
|
|
|
6172
6207
|
\u0415\u0441\u043B\u0438 \u0434\u0430\u043D\u043D\u044B\u0445 \u043D\u0435\u0434\u043E\u0441\u0442\u0430\u0442\u043E\u0447\u043D\u043E \u0438\u043B\u0438 \u0441\u0435\u0442\u0430\u043F \u0441\u043B\u0430\u0431\u044B\u0439 \u2014 \u0432\u0435\u0440\u043D\u0438 "direction": null, quality <= 2 \u0438 \u043E\u0431\u044A\u044F\u0441\u043D\u0438 \u043F\u043E\u0447\u0435\u043C\u0443.
|
|
@@ -6180,6 +6215,10 @@ var init_ai2 = __esm({
|
|
|
6180
6215
|
\u0441\u043B\u043E\u0432\u0430\u0440\u044C strategy-specific \u0444\u0438\u0433\u0443\u0440/\u0433\u0435\u043E\u043C\u0435\u0442\u0440\u0438\u0438 (\u0435\u0441\u043B\u0438 \u0435\u0441\u0442\u044C). \u041A\u043E\u043D\u043A\u0440\u0435\u0442\u043D\u044B\u0435 \u043F\u043E\u043B\u044F \u0437\u0430\u0432\u0438\u0441\u044F\u0442 \u043E\u0442 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438.
|
|
6181
6216
|
- payload.indicators:
|
|
6182
6217
|
\u0441\u043B\u043E\u0432\u0430\u0440\u044C \u0438\u043D\u0434\u0438\u043A\u0430\u0442\u043E\u0440\u043E\u0432/\u0440\u044F\u0434\u043E\u0432 \u043F\u043E \u043C\u043E\u043D\u0435\u0442\u0435 \u0438 BTC; \u0440\u044F\u0434\u044B \u0443\u0436\u0435 \u043E\u0431\u0440\u0435\u0437\u0430\u043D\u044B \u0434\u043E \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0445 5 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439.
|
|
6218
|
+
- payload.additionalIndicators:
|
|
6219
|
+
strategy-specific summary/context fields. \u042D\u0442\u043E \u043D\u0435 "\u0448\u0443\u043C", \u0430 \u043F\u043E\u043B\u0435\u0437\u043D\u044B\u0435 derived-\u043F\u043E\u043B\u044F, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044F \u043F\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u0441\u043F\u0435\u0446\u0438\u0430\u043B\u044C\u043D\u043E \u0434\u043B\u044F \u0440\u0435\u0448\u0435\u043D\u0438\u044F.
|
|
6220
|
+
\u041F\u0440\u0438\u043C\u0435\u0440\u044B: helperFlags, structureContext, spread, correlation, volatilitySummary.
|
|
6221
|
+
\u0415\u0441\u043B\u0438 \u0442\u0430\u043A\u0438\u0435 \u043F\u043E\u043B\u044F \u0435\u0441\u0442\u044C, \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439 \u0438\u0445 \u043A\u0430\u043A \u0431\u043E\u043B\u0435\u0435 \u044F\u0432\u043D\u0443\u044E \u043F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0443, \u0447\u0435\u043C \u043F\u043E\u043F\u044B\u0442\u043A\u0443 \u0437\u0430\u043D\u043E\u0432\u043E \u0432\u044B\u0432\u0435\u0441\u0442\u0438 \u0442\u043E \u0436\u0435 \u0441\u0430\u043C\u043E\u0435 \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u043E lines/points.
|
|
6183
6222
|
\u041F\u0430\u0442\u0442\u0435\u0440\u043D\u044B \u043A\u043B\u044E\u0447\u0435\u0439:
|
|
6184
6223
|
\u2022 \u043C\u043E\u043D\u0435\u0442\u0430: maFast, atrPct, macd..., candles15m/candles1h/candles4h/candles1d, \u0430 \u0442\u0430\u043A\u0436\u0435 *1h/*4h/*1d
|
|
6185
6224
|
\u2022 BTC: btcMaFast, btcAtr, btcMacd..., btcCandles*, \u0430 \u0442\u0430\u043A\u0436\u0435 btc*1h/*4h/*1d
|
|
@@ -6187,41 +6226,42 @@ var init_ai2 = __esm({
|
|
|
6187
6226
|
|
|
6188
6227
|
\u041A\u0430\u043A \u0430\u043D\u0430\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u0442\u044C (\u043F\u0440\u0438\u043E\u0440\u0438\u0442\u0435\u0442\u044B):
|
|
6189
6228
|
1) \u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u043F\u0440\u043E\u0432\u0435\u0440\u044C \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0443 \u0446\u0435\u043D\u044B \u0438 \u0433\u0435\u043E\u043C\u0435\u0442\u0440\u0438\u044E/\u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442 \u0441\u0435\u0442\u0430\u043F\u0430 \u0438\u0437 payload.figures. \u042D\u0442\u043E \u043F\u0440\u0438\u043E\u0440\u0438\u0442\u0435\u0442\u043D\u0435\u0435 \u0438\u043D\u0434\u0438\u043A\u0430\u0442\u043E\u0440\u043E\u0432.
|
|
6190
|
-
2) \u0417\u0430\u0442\u0435\u043C \
|
|
6191
|
-
3) \u0417\u0430\u0442\u0435\u043C \u043F\
|
|
6192
|
-
4) \
|
|
6193
|
-
5) \
|
|
6229
|
+
2) \u0417\u0430\u0442\u0435\u043C \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439 payload.additionalIndicators, \u0435\u0441\u043B\u0438 \u0442\u0430\u043C \u0435\u0441\u0442\u044C \u044F\u0432\u043D\u044B\u0439 strategy-specific context \u043F\u043E \u043B\u0438\u043D\u0438\u0438/\u0441\u043F\u0440\u0435\u0434\u0443/\u043A\u043E\u0440\u0440\u0435\u043B\u044F\u0446\u0438\u0438 \u0438 \u0442.\u043F.
|
|
6230
|
+
3) \u0417\u0430\u0442\u0435\u043C \u043E\u0446\u0435\u043D\u0438 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0435/\u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442 \u043F\u043E \u0438\u043D\u0434\u0438\u043A\u0430\u0442\u043E\u0440\u0430\u043C \u0442\u0435\u043A\u0443\u0449\u0435\u0439 \u043C\u043E\u043D\u0435\u0442\u044B.
|
|
6231
|
+
4) \u0417\u0430\u0442\u0435\u043C \u043F\u0440\u043E\u0432\u0435\u0440\u044C \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442 BTC (\u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0438\u043B\u0438 \u043B\u043E\u043C\u0430\u0435\u0442 \u0438\u0434\u0435\u044E).
|
|
6232
|
+
5) \u0422\u043E\u043B\u044C\u043A\u043E \u043F\u043E\u0441\u043B\u0435 \u044D\u0442\u043E\u0433\u043E \u0432\u044B\u0431\u0435\u0440\u0438 direction, quality \u0438 \u0440\u0435\u0448\u0435\u043D\u0438\u0435 \u043F\u043E \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u043C\u0443 \u0443\u0440\u043E\u0432\u043D\u044E \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F.
|
|
6233
|
+
6) \u0415\u0441\u043B\u0438 \u0435\u0441\u0442\u044C \u0441\u0438\u043B\u044C\u043D\u044B\u0435 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u044B, \u0441\u043D\u0438\u0436\u0430\u0439 quality \u0438\u043B\u0438 \u0441\u0442\u0430\u0432\u044C null.
|
|
6194
6234
|
|
|
6195
6235
|
\u042F\u0432\u043D\u044B\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u0430 \u043F\u0440\u0438 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u0435 \u0441\u0438\u0433\u043D\u0430\u043B\u043E\u0432:
|
|
6196
6236
|
- \u0415\u0441\u043B\u0438 \u0444\u0438\u0433\u0443\u0440\u0430/\u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430 \u0446\u0435\u043D\u044B \u043D\u0435\u0432\u0430\u043B\u0438\u0434\u043D\u044B \u0438\u043B\u0438 \u0441\u043E\u043C\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u044B, \u0438\u043D\u0434\u0438\u043A\u0430\u0442\u043E\u0440\u044B \u043D\u0435 \u0434\u043E\u043B\u0436\u043D\u044B "\u0441\u043F\u0430\u0441\u0430\u0442\u044C" \u0441\u0435\u0442\u0430\u043F.
|
|
6237
|
+
- \u0415\u0441\u043B\u0438 strategy-specific helper fields \u043F\u0440\u044F\u043C\u043E \u0433\u043E\u0432\u043E\u0440\u044F\u0442, \u0447\u0442\u043E \u0441\u0438\u0433\u043D\u0430\u043B \u0435\u0449\u0435 \u043D\u0435 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D / \u0431\u0435\u0437 \u0437\u0430\u043F\u0430\u0441\u0430 / \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043E\u0436\u0438\u0434\u0430\u043D\u0438\u044F, \u043D\u0435 \u0437\u0430\u0432\u044B\u0448\u0430\u0439 quality.
|
|
6197
6238
|
- \u0415\u0441\u043B\u0438 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430 \u043E\u043A, \u043D\u043E BTC \u0438/\u0438\u043B\u0438 \u043A\u043B\u044E\u0447\u0435\u0432\u044B\u0435 \u0438\u043D\u0434\u0438\u043A\u0430\u0442\u043E\u0440\u044B \u0437\u0430\u043C\u0435\u0442\u043D\u043E \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u0443\u044E\u0442, \u043E\u0431\u044B\u0447\u043D\u043E quality <= 3.
|
|
6198
|
-
- \u0415\u0441\u043B\u0438 \
|
|
6239
|
+
- \u0415\u0441\u043B\u0438 \u0442\u0435\u043A\u0443\u0449\u0438\u0439 \u0441\u0438\u0433\u043D\u0430\u043B \u043D\u0435 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D (direction=null), \u0432 comment \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E \u043A\u0440\u0430\u0442\u043A\u043E \u043D\u0430\u0437\u043E\u0432\u0438 \u0433\u043B\u0430\u0432\u043D\u0443\u044E \u043F\u0440\u0438\u0447\u0438\u043D\u0443.
|
|
6199
6240
|
\u0415\u0441\u043B\u0438 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0448\u044C \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u044B\u0435 \u043F\u043E\u043B\u044F, \u0443\u043A\u0430\u0436\u0438 \u0433\u043B\u0430\u0432\u043D\u0443\u044E \u043F\u0440\u0438\u0447\u0438\u043D\u0443 \u0432 "qualityReason" \u0438/\u0438\u043B\u0438 "triggerInvalidation".
|
|
6200
6241
|
|
|
6201
6242
|
\u041F\u0440\u0430\u0432\u0438\u043B\u0430 \u0434\u043B\u044F direction / TP / SL:
|
|
6202
|
-
- direction = LONG \u0442\u043E\u043B\u044C\u043A\u043E \u0435\u0441\u043B\u0438 \
|
|
6243
|
+
- direction = LONG \u0442\u043E\u043B\u044C\u043A\u043E \u0435\u0441\u043B\u0438 \u0434\u0430\u043D\u043D\u044B\u0435 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u044E\u0442 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0439 LONG-\u0441\u0438\u0433\u043D\u0430\u043B; SHORT \u2014 \u0442\u043E\u043B\u044C\u043A\u043E \u0435\u0441\u043B\u0438 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u044E\u0442 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0439 SHORT-\u0441\u0438\u0433\u043D\u0430\u043B; \u0438\u043D\u0430\u0447\u0435 null.
|
|
6203
6244
|
- \u0414\u043B\u044F LONG \u043E\u0431\u044B\u0447\u043D\u043E stopLossPrice < currentPrice < takeProfitPrice.
|
|
6204
6245
|
- \u0414\u043B\u044F SHORT \u043E\u0431\u044B\u0447\u043D\u043E takeProfitPrice < currentPrice < stopLossPrice.
|
|
6205
|
-
-
|
|
6206
|
-
- \u0422\u0440\u0435\u0431\u0443\u0435\u043C\u043E\u0435 \u0441\u043E\u043E\u0442\u043D\u043E\u0448\u0435\u043D\u0438\u0435 reward:risk \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043D\u0435 \u0445\u0443\u0436\u0435 1:3 (\u0442\u043E \u0435\u0441\u0442\u044C reward/risk >= 0.33).
|
|
6246
|
+
- \u041D\u0435 \u043E\u043F\u0442\u0438\u043C\u0438\u0437\u0438\u0440\u0443\u0439 \u0438 \u043D\u0435 \u043F\u0435\u0440\u0435\u0441\u0447\u0438\u0442\u044B\u0432\u0430\u0439 TP/SL \u043F\u043E\u0434 "\u043B\u0443\u0447\u0448\u0443\u044E \u0441\u0434\u0435\u043B\u043A\u0443"; \u0442\u043E\u043B\u044C\u043A\u043E \u043E\u0446\u0435\u043D\u0438 \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D\u043D\u043E\u0441\u0442\u044C \u0443\u0436\u0435 \u043F\u0435\u0440\u0435\u0434\u0430\u043D\u043D\u044B\u0445 \u0443\u0440\u043E\u0432\u043D\u0435\u0439.
|
|
6207
6247
|
- \u0415\u0441\u043B\u0438 direction = null, \u0442\u043E takeProfitPrice = null \u0438 stopLossPrice = null.
|
|
6208
6248
|
- \u0415\u0441\u043B\u0438 needRetest = false, \u0442\u043E retestPrice = null.
|
|
6209
6249
|
- \u0415\u0441\u043B\u0438 needRetest = true, retestPrice \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u0443\u043A\u0430\u0437\u0430\u043D (finite number) \u0438 \u0441\u0432\u044F\u0437\u0430\u043D \u0441 \u0443\u0440\u043E\u0432\u043D\u0435\u043C \u0440\u0435\u0442\u0435\u0441\u0442\u0430/\u043F\u0440\u043E\u0431\u043E\u044F.
|
|
6210
6250
|
- Sanity-check \u043F\u0435\u0440\u0435\u0434 \u043E\u0442\u0432\u0435\u0442\u043E\u043C: \u043F\u0440\u043E\u0432\u0435\u0440\u044C \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D\u043D\u043E\u0441\u0442\u044C direction \u0441 TP/SL \u0438 \u0442\u0435\u043A\u0443\u0449\u0435\u0439 \u0446\u0435\u043D\u043E\u0439.
|
|
6211
6251
|
|
|
6212
6252
|
\u0428\u043A\u0430\u043B\u0430 quality (\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439 \u0432\u0441\u044E \u0448\u043A\u0430\u043B\u0443, \u043D\u0435 \u0437\u0430\u0432\u044B\u0448\u0430\u0439):
|
|
6213
|
-
- 1: \u043F\u043B\u043E\u0445\u043E\u0439/\u0445\u0430\u043E\u0442\u0438\u0447\u043D\u044B\u0439 \u0441\u0435\u0442\u0430\u043F, \u0441\u0438\u043B\u044C\u043D\u044B\u0435 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u044B, \
|
|
6214
|
-
- 2: \u0441\u043B\u0430\u0431\u044B\u0439 \u0441\u0435\u0442\u0430\u043F, \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0439 \u043C\u0430\u043B\u043E, \
|
|
6215
|
-
- 3: \u0441\u0440\u0435\u0434\u043D\u0438\u0439 \u0441\u0435\u0442\u0430\u043F, \
|
|
6216
|
-
- 4: \u0445\u043E\u0440\u043E\u0448\u0438\u0439 \u0441\u0435\u0442\u0430\u043F, \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0439, \u0440\
|
|
6217
|
-
- 5: \u043E\u0447\u0435\u043D\u044C \u0441\u0438\u043B\u044C\u043D\u044B\u0439 \u0441\u0435\u0442\u0430\u043F, \u0447\u0438\u0441\u0442\u0430\u044F \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430 + \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F + \
|
|
6253
|
+
- 1: \u043F\u043B\u043E\u0445\u043E\u0439/\u0445\u0430\u043E\u0442\u0438\u0447\u043D\u044B\u0439 \u0441\u0435\u0442\u0430\u043F, \u0441\u0438\u043B\u044C\u043D\u044B\u0435 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u044B, \u0441\u0438\u0433\u043D\u0430\u043B \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u043E \u043D\u0435 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D
|
|
6254
|
+
- 2: \u0441\u043B\u0430\u0431\u044B\u0439 \u0441\u0435\u0442\u0430\u043F, \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0439 \u043C\u0430\u043B\u043E, \u0441\u0438\u0433\u043D\u0430\u043B \u043F\u043E\u043A\u0430 \u0441\u043A\u043E\u0440\u0435\u0435 watch/reject
|
|
6255
|
+
- 3: \u0441\u0440\u0435\u0434\u043D\u0438\u0439 \u0441\u0435\u0442\u0430\u043F, \u0447\u0430\u0441\u0442\u044C \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u044B \u0435\u0441\u0442\u044C, \u043D\u043E \u043E\u0441\u0442\u0430\u044E\u0442\u0441\u044F \u0437\u0430\u043C\u0435\u0442\u043D\u044B\u0435 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u044B
|
|
6256
|
+
- 4: \u0445\u043E\u0440\u043E\u0448\u0438\u0439 \u0441\u0435\u0442\u0430\u043F, \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0439, \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430 \u0432 \u0446\u0435\u043B\u043E\u043C \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D\u0430
|
|
6257
|
+
- 5: \u043E\u0447\u0435\u043D\u044C \u0441\u0438\u043B\u044C\u043D\u044B\u0439 \u0441\u0435\u0442\u0430\u043F, \u0447\u0438\u0441\u0442\u0430\u044F \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430 + \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F + \u0432\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u044F\u044F \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D\u043D\u043E\u0441\u0442\u044C \u0443\u0440\u043E\u0432\u043D\u0435\u0439
|
|
6218
6258
|
|
|
6219
6259
|
\u0422\u0440\u0435\u0431\u043E\u0432\u0430\u043D\u0438\u044F \u043A \u043F\u043E\u043B\u0435\u0437\u043D\u043E\u043C\u0443 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u043E\u043C\u0443 \u0430\u043D\u0430\u043B\u0438\u0437\u0443 (\u0431\u0435\u0437 \u0432\u043E\u0434\u044B):
|
|
6220
|
-
- \u0423\u043A\u0430\u0436\u0438 2-4 \u043A\u043E\u043D\u043A\u0440\u0435\u0442\u043D\u044B\u0445 \u0444\u0430\u043A\u0442\u043E\u0440\u0430 "\u0437\u0430" \u0438\u043B\u0438 "\u043F\u0440\u043E\u0442\u0438\u0432" \
|
|
6260
|
+
- \u0423\u043A\u0430\u0436\u0438 2-4 \u043A\u043E\u043D\u043A\u0440\u0435\u0442\u043D\u044B\u0445 \u0444\u0430\u043A\u0442\u043E\u0440\u0430 "\u0437\u0430" \u0438\u043B\u0438 "\u043F\u0440\u043E\u0442\u0438\u0432" \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F \u0441\u0438\u0433\u043D\u0430\u043B\u0430 \u0432 "confirmations".
|
|
6221
6261
|
- \u041E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E \u0443\u043F\u043E\u043C\u044F\u043D\u0438 \u0440\u043E\u043B\u044C \u043A\u043B\u044E\u0447\u0435\u0432\u043E\u0439 \u0444\u0438\u0433\u0443\u0440\u044B/\u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u044B \u0441\u0435\u0442\u0430\u043F\u0430 (\u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440 \u043F\u0440\u043E\u0431\u043E\u0439/\u0440\u0435\u0442\u0435\u0441\u0442/\u043B\u043E\u0436\u043D\u044B\u0439 \u043F\u0440\u043E\u0431\u043E\u0439/\u043A\u0430\u0441\u0430\u043D\u0438\u0435/\u043D\u0435\u0442 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F).
|
|
6222
6262
|
- \u041E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E \u0443\u043F\u043E\u043C\u044F\u043D\u0438 BTC-\u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442 (\u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442, \u043D\u0435\u0439\u0442\u0440\u0430\u043B\u0435\u043D \u0438\u043B\u0438 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u0443\u0435\u0442).
|
|
6223
6263
|
- \u041E\u0431\u044A\u044F\u0441\u043D\u0438, \u043F\u043E\u0447\u0435\u043C\u0443 quality \u0438\u043C\u0435\u043D\u043D\u043E \u0442\u0430\u043A\u043E\u0439.
|
|
6224
|
-
- \u0415\u0441\u043B\u0438 \u043D\u0435 \u0432\
|
|
6264
|
+
- \u0415\u0441\u043B\u0438 signal \u043D\u0435 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D (direction=null), \u043F\u0440\u044F\u043C\u043E \u0443\u043A\u0430\u0436\u0438 \u0447\u0442\u043E \u0434\u043E\u043B\u0436\u043D\u043E \u0438\u0437\u043C\u0435\u043D\u0438\u0442\u044C\u0441\u044F \u0434\u043B\u044F \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F \u0441\u0438\u0433\u043D\u0430\u043B\u0430.
|
|
6225
6265
|
- \u0412 "retestPlan" \u043D\u0435 \u043F\u0438\u0448\u0438 \u0442\u0435\u0445\u043D\u0438\u0447\u0435\u0441\u043A\u0438\u0439 \u0448\u0430\u0431\u043B\u043E\u043D \u0432\u0440\u043E\u0434\u0435 "needRetest=false @ null"; \u043F\u0438\u0448\u0438 \u0447\u0435\u043B\u043E\u0432\u0435\u0447\u0435\u0441\u043A\u043E\u0435 \u043E\u0431\u044A\u044F\u0441\u043D\u0435\u043D\u0438\u0435.
|
|
6226
6266
|
- \u041D\u0435 \u043F\u043E\u0432\u0442\u043E\u0440\u044F\u0439 \u043F\u0440\u043E\u0441\u0442\u043E \u043F\u043E\u043B\u044F JSON; \u0434\u0430\u0439 \u0441\u043C\u044B\u0441\u043B \u0438 \u0440\u0435\u0448\u0435\u043D\u0438\u0435.
|
|
6227
6267
|
|
|
@@ -6231,49 +6271,142 @@ var init_ai2 = __esm({
|
|
|
6231
6271
|
- \u0415\u0441\u043B\u0438 \u0434\u0430\u043D\u043D\u044B\u0445 \u043C\u0430\u043B\u043E \u0434\u043B\u044F \u0443\u0432\u0435\u0440\u0435\u043D\u043D\u043E\u0433\u043E \u0432\u044B\u0432\u043E\u0434\u0430, \u0441\u043D\u0438\u0436\u0430\u0439 quality \u0438 \u0444\u043E\u0440\u043C\u0443\u043B\u0438\u0440\u0443\u0439 \u0432\u044B\u0432\u043E\u0434 \u043E\u0441\u0442\u043E\u0440\u043E\u0436\u043D\u043E.
|
|
6232
6272
|
|
|
6233
6273
|
\u041A\u043E\u0440\u043E\u0442\u043A\u0438\u0435 \u043F\u0440\u0438\u043C\u0435\u0440\u044B (few-shot, \u0444\u043E\u0440\u043C\u0430\u0442 \u043E\u0442\u0432\u0435\u0442\u0430):
|
|
6234
|
-
{"direction":"LONG","quality":4,"needRetest":true,"retestPrice":100.2,"takeProfitPrice":101.5,"stopLossPrice":98.9,"setup":"\u0412\u0435\u0440\u043E\u044F\u0442\u043D\u044B\u0439 \u043F\u0440\u043E\u0431\u043E\u0439 \u0442\u0440\u0435\u043D\u0434\u043E\u0432\u043E\u0439 \u0432\u0432\u0435\u0440\u0445, \u043D\u043E \
|
|
6235
|
-
{"direction":null,"quality":2,"needRetest":false,"retestPrice":null,"takeProfitPrice":null,"stopLossPrice":null,"setup":"\u041A\u0430\u0441\u0430\u043D\u0438\u0435/\u0448\u0443\u043C \u0443 \u0442\u0440\u0435\u043D\u0434\u043E\u0432\u043E\u0439 \u0431\u0435\u0437 \u0443\u0432\u0435\u0440\u0435\u043D\u043D\u043E\u0433\u043E \u043F\u0440\u043E\u0431\u043E\u044F.","confirmations":"\u0418\u043D\u0434\u0438\u043A\u0430\u0442\u043E\u0440\u044B \u0441\u043C\u0435\u0448\u0430\u043D\u043D\u044B\u0435 \u0438 \u043D\u0435 \u0434\u0430\u044E\u0442 \u0441\u0438\u043B\u044C\u043D\u043E\u0433\u043E \u043F\u0440\u0435\u0438\u043C\u0443\u0449\u0435\u0441\u0442\u0432\u0430.","btcContext":"BTC \u0441\u043A\u043E\u0440\u0435\u0435 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u0443\u0435\u0442 \u0438\u043B\u0438 \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0438\
|
|
6274
|
+
{"direction":"LONG","quality":4,"needRetest":true,"retestPrice":100.2,"takeProfitPrice":101.5,"stopLossPrice":98.9,"setup":"\u0412\u0435\u0440\u043E\u044F\u0442\u043D\u044B\u0439 \u043F\u0440\u043E\u0431\u043E\u0439 \u0442\u0440\u0435\u043D\u0434\u043E\u0432\u043E\u0439 \u0432\u0432\u0435\u0440\u0445, \u043D\u043E \u0434\u043B\u044F \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F \u0441\u0438\u0433\u043D\u0430\u043B\u0430 \u043D\u0443\u0436\u043D\u0430 \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u0443\u0440\u043E\u0432\u043D\u044F.","confirmations":"\u041F\u043E \u043C\u043E\u043D\u0435\u0442\u0435 \u0435\u0441\u0442\u044C \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0430 \u0438\u043C\u043F\u0443\u043B\u044C\u0441\u0430 \u0431\u0435\u0437 \u044F\u0432\u043D\u043E\u0433\u043E \u043F\u0435\u0440\u0435\u0433\u0440\u0435\u0432\u0430, \u043D\u043E \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0435 \u0435\u0449\u0435 \u043D\u0435 \u0438\u0434\u0435\u0430\u043B\u044C\u043D\u043E\u0435.","btcContext":"BTC \u043D\u0435\u0439\u0442\u0440\u0430\u043B\u044C\u043D\u043E \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0438\u0434\u0435\u044E \u0438 \u043D\u0435 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u0443\u0435\u0442 \u0441 \u0442\u0435\u043A\u0443\u0449\u0438\u043C LONG-\u0441\u0438\u0433\u043D\u0430\u043B\u043E\u043C.","retestPlan":"\u041A\u043B\u044E\u0447\u0435\u0432\u043E\u0439 \u0443\u0440\u043E\u0432\u0435\u043D\u044C 100.2: \u0443\u0434\u0435\u0440\u0436\u0430\u043D\u0438\u0435 \u0432\u044B\u0448\u0435 \u043D\u0435\u0433\u043E \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0443 \u0441\u0438\u0433\u043D\u0430\u043B\u0430.","riskLevels":"\u041F\u0435\u0440\u0435\u0434\u0430\u043D\u043D\u044B\u0435 TP/SL \u0441\u0442\u043E\u044F\u0442 \u043F\u043E \u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u044B\u0435 \u0441\u0442\u043E\u0440\u043E\u043D\u044B \u043E\u0442 \u0442\u0435\u043A\u0443\u0449\u0435\u0439 \u0446\u0435\u043D\u044B \u0438 \u0432\u044B\u0433\u043B\u044F\u0434\u044F\u0442 \u0432\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u0435 \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D\u043D\u043E.","qualityReason":"Quality=4: \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430 \u0445\u043E\u0440\u043E\u0448\u0430\u044F, \u043D\u043E \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0435 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0435 \u043F\u043E \u0443\u0440\u043E\u0432\u043D\u044E \u0435\u0449\u0435 \u0436\u0435\u043B\u0430\u0442\u0435\u043B\u044C\u043D\u043E.","triggerInvalidation":"\u0421\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442\u0441\u044F \u043F\u0440\u0438 \u0443\u0434\u0435\u0440\u0436\u0430\u043D\u0438\u0438 \u0443\u0440\u043E\u0432\u043D\u044F; \u0433\u0438\u043F\u043E\u0442\u0435\u0437\u0430 \u043E\u0441\u043B\u0430\u0431\u0435\u0432\u0430\u0435\u0442 \u043F\u0440\u0438 \u0432\u043E\u0437\u0432\u0440\u0430\u0442\u0435 \u043F\u043E\u0434 \u043B\u0438\u043D\u0438\u044E."}
|
|
6275
|
+
{"direction":null,"quality":2,"needRetest":false,"retestPrice":null,"takeProfitPrice":null,"stopLossPrice":null,"setup":"\u041A\u0430\u0441\u0430\u043D\u0438\u0435/\u0448\u0443\u043C \u0443 \u0442\u0440\u0435\u043D\u0434\u043E\u0432\u043E\u0439 \u0431\u0435\u0437 \u0443\u0432\u0435\u0440\u0435\u043D\u043D\u043E\u0433\u043E \u043F\u0440\u043E\u0431\u043E\u044F.","confirmations":"\u0418\u043D\u0434\u0438\u043A\u0430\u0442\u043E\u0440\u044B \u0441\u043C\u0435\u0448\u0430\u043D\u043D\u044B\u0435 \u0438 \u043D\u0435 \u0434\u0430\u044E\u0442 \u0441\u0438\u043B\u044C\u043D\u043E\u0433\u043E \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u043E\u0433\u043E \u043F\u0440\u0435\u0438\u043C\u0443\u0449\u0435\u0441\u0442\u0432\u0430.","btcContext":"BTC \u0441\u043A\u043E\u0440\u0435\u0435 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u0443\u0435\u0442 \u0438\u043B\u0438 \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u0435\u043A\u0443\u0449\u0443\u044E \u0433\u0438\u043F\u043E\u0442\u0435\u0437\u0443.","retestPlan":"\u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0439 \u0443\u0440\u043E\u0432\u0435\u043D\u044C \u043F\u043E\u043A\u0430 \u0440\u0430\u043D\u043E \u043E\u0446\u0435\u043D\u0438\u0432\u0430\u0442\u044C, \u043F\u043E\u0442\u043E\u043C\u0443 \u0447\u0442\u043E \u043D\u0435\u0442 \u0441\u0430\u043C\u043E\u0433\u043E \u0444\u0430\u043A\u0442\u0430 \u043A\u0430\u0447\u0435\u0441\u0442\u0432\u0435\u043D\u043D\u043E\u0433\u043E \u043F\u0440\u043E\u0431\u043E\u044F.","riskLevels":"\u041F\u0435\u0440\u0435\u0434\u0430\u043D\u043D\u044B\u0435 \u0443\u0440\u043E\u0432\u043D\u0438 \u043F\u043E\u043A\u0430 \u043D\u0435 \u0441\u0442\u043E\u0438\u0442 \u0441\u0447\u0438\u0442\u0430\u0442\u044C \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u043D\u044B\u043C\u0438 \u0438\u0437-\u0437\u0430 \u0441\u043B\u0430\u0431\u043E\u0439 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u044B.","qualityReason":"Quality=2: timing \u0441\u043B\u0430\u0431\u044B\u0439 \u0438 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0439 \u043C\u0430\u043B\u043E.","triggerInvalidation":"\u0416\u0434\u0430\u0442\u044C \u044F\u0432\u043D\u044B\u0439 \u043F\u0440\u043E\u0431\u043E\u0439 \u0438 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0435 \u043F\u043E \u043C\u043E\u043D\u0435\u0442\u0435 \u0438 BTC."}
|
|
6236
6276
|
|
|
6237
6277
|
\u0412\u0435\u0440\u043D\u0438 \u0442\u043E\u043B\u044C\u043A\u043E JSON-\u043E\u0431\u044A\u0435\u043A\u0442, \u0431\u0435\u0437 \u043B\u0438\u0448\u043D\u0438\u0445 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432.
|
|
6238
6278
|
${signal ? buildAiSystemPromptAddonByStrategy(signal) : ""}
|
|
6239
6279
|
`;
|
|
6240
6280
|
buildAiPayload = (signal) => buildAiPayloadByStrategy(signal);
|
|
6281
|
+
getDeterministicAiGateContext = (payload) => {
|
|
6282
|
+
const additionalIndicators = asRecord(payload.additionalIndicators);
|
|
6283
|
+
const candidates = [
|
|
6284
|
+
additionalIndicators,
|
|
6285
|
+
...Object.values(additionalIndicators ?? {}).map(asRecord)
|
|
6286
|
+
].filter((value) => Boolean(value));
|
|
6287
|
+
return candidates.find(
|
|
6288
|
+
(candidate) => Array.isArray(candidate.structuralHardBlockReasons) || typeof candidate.approvalAllowedNow === "boolean"
|
|
6289
|
+
) ?? null;
|
|
6290
|
+
};
|
|
6241
6291
|
buildAiHumanPrompt = (signal, payload = buildAiPayload(signal)) => `
|
|
6242
|
-
\u041F\u0440\u043E\u0430\u043D\u0430\u043B\u0438\u0437\u0438\u0440\u0443\u0439 \u0441\
|
|
6243
|
-
\
|
|
6292
|
+
\u041F\u0440\u043E\u0430\u043D\u0430\u043B\u0438\u0437\u0438\u0440\u0443\u0439 \u0443\u0436\u0435 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043D\u043D\u044B\u0439 \u0432\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u0438\u0439 \u0441\u0438\u0433\u043D\u0430\u043B \u043F\u043E ${signal.symbol}. \u0418\u0441\u0445\u043E\u0434\u043D\u044B\u0439 \u0441\u0438\u0433\u043D\u0430\u043B \u0438\u043C\u0435\u0435\u0442 \u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 ${signal.direction}.
|
|
6293
|
+
\u042D\u0442\u043E \u0437\u0430\u0434\u0430\u0447\u0430 \u043A\u043B\u0430\u0441\u0441\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u0438/\u0430\u0443\u0434\u0438\u0442\u0430 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u044B, \u0430 \u043D\u0435 \u0440\u0435\u043A\u043E\u043C\u0435\u043D\u0434\u0430\u0446\u0438\u044F \u043A \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044E. \u041E\u043F\u0440\u0435\u0434\u0435\u043B\u0438, \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442 \u043B\u0438 \u0442\u0435\u043A\u0443\u0449\u0430\u044F \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0439 \u0441\u0438\u0433\u043D\u0430\u043B, \u043D\u0430\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u043E\u043D \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u043E \u0441\u0435\u0439\u0447\u0430\u0441, \u043D\u0443\u0436\u0435\u043D \u043B\u0438 \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0439 confirmation level, \u0438 \u0432\u044B\u0433\u043B\u044F\u0434\u044F\u0442 \u043B\u0438 \u0443\u0436\u0435 \u043F\u0435\u0440\u0435\u0434\u0430\u043D\u043D\u044B\u0435 \u0432 payload.signal.prices \u0443\u0440\u043E\u0432\u043D\u0438 \u0432\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u0435 \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D\u043D\u044B\u043C\u0438. \u041D\u0435 \u0444\u043E\u0440\u043C\u0438\u0440\u0443\u0439 \u043D\u043E\u0432\u0443\u044E \u0433\u0438\u043F\u043E\u0442\u0435\u0437\u0443 \u0432\u043C\u0435\u0441\u0442\u043E \u0438\u0441\u0445\u043E\u0434\u043D\u043E\u0433\u043E \u0441\u0438\u0433\u043D\u0430\u043B\u0430 \u0438 \u043D\u0435 \u043F\u0440\u0438\u0434\u0443\u043C\u044B\u0432\u0430\u0439 \u043D\u043E\u0432\u044B\u0435 \u0443\u0440\u043E\u0432\u043D\u0438; \u0432\u0435\u0440\u043D\u0438 \u0442\u043E\u043B\u044C\u043A\u043E JSON \u0432 \u0437\u0430\u0434\u0430\u043D\u043D\u043E\u043C \u0444\u043E\u0440\u043C\u0430\u0442\u0435.
|
|
6244
6294
|
|
|
6245
6295
|
\u0414\u0430\u043D\u043D\u044B\u0435 \u0441\u0434\u0435\u043B\u043A\u0438:
|
|
6246
6296
|
${JSON.stringify(payload)}
|
|
6247
6297
|
${buildAiHumanPromptAddonByStrategy(signal, payload)}
|
|
6248
6298
|
`;
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
const
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6299
|
+
DEFAULT_AI_MODEL = "openai/gpt-5-mini";
|
|
6300
|
+
userSettingsCache = /* @__PURE__ */ new Map();
|
|
6301
|
+
aiModelCache = /* @__PURE__ */ new Map();
|
|
6302
|
+
getAiModelCacheKey = (userName, modelName) => `${userName}::${modelName}`;
|
|
6303
|
+
getOpenRouterModelKwargs = (apiEndpoint) => {
|
|
6304
|
+
const endpoint = String(apiEndpoint ?? "").trim();
|
|
6305
|
+
if (!endpoint) {
|
|
6306
|
+
return {};
|
|
6307
|
+
}
|
|
6308
|
+
let hostname = "";
|
|
6309
|
+
try {
|
|
6310
|
+
hostname = new URL(endpoint).hostname;
|
|
6311
|
+
} catch {
|
|
6312
|
+
hostname = endpoint;
|
|
6313
|
+
}
|
|
6314
|
+
if (!hostname.toLowerCase().includes("openrouter")) {
|
|
6315
|
+
return {};
|
|
6316
|
+
}
|
|
6317
|
+
return {
|
|
6318
|
+
provider: {
|
|
6319
|
+
ignore: ["azure"]
|
|
6267
6320
|
}
|
|
6268
|
-
}
|
|
6269
|
-
|
|
6321
|
+
};
|
|
6322
|
+
};
|
|
6323
|
+
getAiSettings = async (userName = "root") => {
|
|
6324
|
+
let settingsPromise = userSettingsCache.get(userName);
|
|
6325
|
+
if (!settingsPromise) {
|
|
6326
|
+
settingsPromise = (0, import_userSettings.getUserSettings)(userName);
|
|
6327
|
+
settingsPromise.catch(() => {
|
|
6328
|
+
userSettingsCache.delete(userName);
|
|
6329
|
+
});
|
|
6330
|
+
userSettingsCache.set(userName, settingsPromise);
|
|
6331
|
+
}
|
|
6332
|
+
const settings = await settingsPromise;
|
|
6333
|
+
if (!settings.OPENAI_API_KEY || !settings.OPENAI_API_ENDPOINT) {
|
|
6334
|
+
throw new Error(`AI settings are incomplete for user ${userName}`);
|
|
6335
|
+
}
|
|
6336
|
+
return settings;
|
|
6337
|
+
};
|
|
6338
|
+
createAiModel = async (userName = "root", modelName = DEFAULT_AI_MODEL) => {
|
|
6339
|
+
const cacheKey = getAiModelCacheKey(userName, modelName);
|
|
6340
|
+
let modelPromise = aiModelCache.get(cacheKey);
|
|
6341
|
+
if (!modelPromise) {
|
|
6342
|
+
modelPromise = (async () => {
|
|
6343
|
+
const [{ ChatOpenAI }, settings] = await Promise.all([
|
|
6344
|
+
import("@langchain/openai"),
|
|
6345
|
+
getAiSettings(userName)
|
|
6346
|
+
]);
|
|
6347
|
+
const modelKwargs = getOpenRouterModelKwargs(
|
|
6348
|
+
settings.OPENAI_API_ENDPOINT
|
|
6349
|
+
);
|
|
6350
|
+
return new ChatOpenAI({
|
|
6351
|
+
temperature: 0.2,
|
|
6352
|
+
modelName,
|
|
6353
|
+
apiKey: settings.OPENAI_API_KEY,
|
|
6354
|
+
...Object.keys(modelKwargs).length ? { modelKwargs } : {},
|
|
6355
|
+
configuration: {
|
|
6356
|
+
baseURL: settings.OPENAI_API_ENDPOINT,
|
|
6357
|
+
defaultHeaders: {
|
|
6358
|
+
"HTTP-Referer": "https://tradejs.dev",
|
|
6359
|
+
"X-Title": "Inv"
|
|
6360
|
+
}
|
|
6361
|
+
}
|
|
6362
|
+
});
|
|
6363
|
+
})();
|
|
6364
|
+
modelPromise.catch(() => {
|
|
6365
|
+
aiModelCache.delete(cacheKey);
|
|
6366
|
+
});
|
|
6367
|
+
aiModelCache.set(cacheKey, modelPromise);
|
|
6368
|
+
}
|
|
6369
|
+
return modelPromise;
|
|
6370
|
+
};
|
|
6371
|
+
getAiModel = async (userName = "root", modelName = DEFAULT_AI_MODEL) => {
|
|
6372
|
+
try {
|
|
6373
|
+
return await createAiModel(userName, modelName);
|
|
6374
|
+
} catch (error) {
|
|
6375
|
+
aiModelCache.delete(getAiModelCacheKey(userName, modelName));
|
|
6376
|
+
userSettingsCache.delete(userName);
|
|
6377
|
+
throw error;
|
|
6378
|
+
}
|
|
6379
|
+
};
|
|
6380
|
+
resetAiRuntimeCache = () => {
|
|
6381
|
+
aiModelCache.clear();
|
|
6382
|
+
userSettingsCache.clear();
|
|
6383
|
+
};
|
|
6384
|
+
ensureAiStrategyPluginsLoaded = async () => {
|
|
6385
|
+
await ensureStrategyPluginsLoaded();
|
|
6386
|
+
};
|
|
6387
|
+
buildAiPrompts = (signal) => {
|
|
6270
6388
|
const payload = buildAiPayload(signal);
|
|
6389
|
+
return {
|
|
6390
|
+
systemPrompt: buildAiSystemPrompt(signal),
|
|
6391
|
+
humanPrompt: buildAiHumanPrompt(signal, payload)
|
|
6392
|
+
};
|
|
6393
|
+
};
|
|
6394
|
+
runAiPrompt = async ({ systemPrompt, humanPrompt }, options = {}) => {
|
|
6395
|
+
if (options.signal) {
|
|
6396
|
+
await ensureAiStrategyPluginsLoaded();
|
|
6397
|
+
}
|
|
6398
|
+
const [{ HumanMessage, SystemMessage }, model] = await Promise.all([
|
|
6399
|
+
import("@langchain/core/messages"),
|
|
6400
|
+
getAiModel(options.userName, options.model)
|
|
6401
|
+
]);
|
|
6402
|
+
const messages = [];
|
|
6403
|
+
messages.push(new SystemMessage(systemPrompt));
|
|
6271
6404
|
messages.push(
|
|
6272
6405
|
new HumanMessage({
|
|
6273
6406
|
content: [
|
|
6274
6407
|
{
|
|
6275
6408
|
type: "text",
|
|
6276
|
-
text:
|
|
6409
|
+
text: humanPrompt
|
|
6277
6410
|
}
|
|
6278
6411
|
]
|
|
6279
6412
|
})
|
|
@@ -6282,7 +6415,51 @@ ${buildAiHumanPromptAddonByStrategy(signal, payload)}
|
|
|
6282
6415
|
const parsed = parseAIResponse(
|
|
6283
6416
|
normalizeResponseContent(response.content)
|
|
6284
6417
|
);
|
|
6285
|
-
const
|
|
6418
|
+
const normalized = normalizeAnalysis(parsed);
|
|
6419
|
+
if (!options.signal) {
|
|
6420
|
+
return normalized;
|
|
6421
|
+
}
|
|
6422
|
+
return postProcessAiAnalysisByStrategy(
|
|
6423
|
+
options.signal,
|
|
6424
|
+
normalized,
|
|
6425
|
+
options.payload
|
|
6426
|
+
);
|
|
6427
|
+
};
|
|
6428
|
+
runAiPromptLocal = async (signal, options = {}) => {
|
|
6429
|
+
await ensureAiStrategyPluginsLoaded();
|
|
6430
|
+
const payload = options.payload ?? buildAiPayload(signal);
|
|
6431
|
+
const gateContext = getDeterministicAiGateContext(payload);
|
|
6432
|
+
const signalDirection = getSignalDirection(signal);
|
|
6433
|
+
const deterministicQuality = getDeterministicQuality(gateContext);
|
|
6434
|
+
const approvalAllowedNow = typeof gateContext?.approvalAllowedNow === "boolean" ? gateContext.approvalAllowedNow : deterministicQuality >= 4;
|
|
6435
|
+
return postProcessAiAnalysisByStrategy(
|
|
6436
|
+
signal,
|
|
6437
|
+
{
|
|
6438
|
+
direction: approvalAllowedNow ? signalDirection : null,
|
|
6439
|
+
quality: deterministicQuality,
|
|
6440
|
+
needRetest: !approvalAllowedNow,
|
|
6441
|
+
retestPrice: null,
|
|
6442
|
+
takeProfitPrice: approvalAllowedNow ? signal.prices?.takeProfitPrice ?? null : null,
|
|
6443
|
+
stopLossPrice: approvalAllowedNow ? signal.prices?.stopLossPrice ?? null : null
|
|
6444
|
+
},
|
|
6445
|
+
payload
|
|
6446
|
+
);
|
|
6447
|
+
};
|
|
6448
|
+
askAI = async (signal, options = {}) => {
|
|
6449
|
+
const { symbol } = signal;
|
|
6450
|
+
await ensureAiStrategyPluginsLoaded();
|
|
6451
|
+
const payload = buildAiPayload(signal);
|
|
6452
|
+
const content = await runAiPrompt(
|
|
6453
|
+
{
|
|
6454
|
+
systemPrompt: buildAiSystemPrompt(signal),
|
|
6455
|
+
humanPrompt: buildAiHumanPrompt(signal, payload)
|
|
6456
|
+
},
|
|
6457
|
+
{
|
|
6458
|
+
...options,
|
|
6459
|
+
signal,
|
|
6460
|
+
payload
|
|
6461
|
+
}
|
|
6462
|
+
);
|
|
6286
6463
|
await (0, import_redis.setData)(import_redis.redisKeys.analysis(symbol, signal.signalId), content);
|
|
6287
6464
|
return content;
|
|
6288
6465
|
};
|
|
@@ -6292,10 +6469,12 @@ ${buildAiHumanPromptAddonByStrategy(signal, payload)}
|
|
|
6292
6469
|
// src/strategies.ts
|
|
6293
6470
|
var strategies_exports = {};
|
|
6294
6471
|
__export(strategies_exports, {
|
|
6472
|
+
DEFAULT_AI_MODEL: () => DEFAULT_AI_MODEL,
|
|
6295
6473
|
MAX_AI_SERIES_POINTS: () => MAX_AI_SERIES_POINTS,
|
|
6296
6474
|
askAI: () => askAI,
|
|
6297
6475
|
buildAiHumanPrompt: () => buildAiHumanPrompt,
|
|
6298
6476
|
buildAiPayload: () => buildAiPayload,
|
|
6477
|
+
buildAiPrompts: () => buildAiPrompts,
|
|
6299
6478
|
buildAiSystemPrompt: () => buildAiSystemPrompt,
|
|
6300
6479
|
closeOppositePositionsBeforeOpen: () => closeOppositePositionsBeforeOpen,
|
|
6301
6480
|
createCloseOppositeBeforePlaceOrderHook: () => createCloseOppositeBeforePlaceOrderHook,
|
|
@@ -6303,18 +6482,24 @@ __export(strategies_exports, {
|
|
|
6303
6482
|
enrichSignalWithAi: () => enrichSignalWithAi,
|
|
6304
6483
|
enrichSignalWithMl: () => enrichSignalWithMl,
|
|
6305
6484
|
enrichSignalWithMlAi: () => enrichSignalWithMlAi,
|
|
6485
|
+
ensureAiStrategyPluginsLoaded: () => ensureAiStrategyPluginsLoaded,
|
|
6306
6486
|
ensureIndicatorPluginsLoaded: () => ensureIndicatorPluginsLoaded,
|
|
6307
6487
|
ensureStrategyPluginsLoaded: () => ensureStrategyPluginsLoaded,
|
|
6308
6488
|
executeEntryOrder: () => executeEntryOrder,
|
|
6309
6489
|
getAvailableStrategyNames: () => getAvailableStrategyNames,
|
|
6490
|
+
getDeterministicAiGateContext: () => getDeterministicAiGateContext,
|
|
6491
|
+
getOpenRouterModelKwargs: () => getOpenRouterModelKwargs,
|
|
6310
6492
|
getRegisteredManifests: () => getRegisteredManifests,
|
|
6311
6493
|
getRegisteredStrategies: () => getRegisteredStrategies,
|
|
6312
6494
|
getStrategyCreator: () => getStrategyCreator,
|
|
6313
6495
|
getStrategyManifest: () => getStrategyManifest,
|
|
6314
6496
|
isKnownStrategy: () => isKnownStrategy,
|
|
6315
6497
|
registerStrategyEntries: () => registerStrategyEntries,
|
|
6498
|
+
resetAiRuntimeCache: () => resetAiRuntimeCache,
|
|
6316
6499
|
resetStrategyRegistryCache: () => resetStrategyRegistryCache,
|
|
6317
6500
|
resolveStrategyConfig: () => resolveStrategyConfig,
|
|
6501
|
+
runAiPrompt: () => runAiPrompt,
|
|
6502
|
+
runAiPromptLocal: () => runAiPromptLocal,
|
|
6318
6503
|
strategies: () => strategies,
|
|
6319
6504
|
trimSeriesDeep: () => trimSeriesDeep
|
|
6320
6505
|
});
|
|
@@ -6523,6 +6708,7 @@ var enrichSignalWithMl = async ({
|
|
|
6523
6708
|
var enrichSignalWithAi = async ({
|
|
6524
6709
|
signal,
|
|
6525
6710
|
symbol,
|
|
6711
|
+
userName,
|
|
6526
6712
|
direction,
|
|
6527
6713
|
env,
|
|
6528
6714
|
ai
|
|
@@ -6532,7 +6718,7 @@ var enrichSignalWithAi = async ({
|
|
|
6532
6718
|
}
|
|
6533
6719
|
try {
|
|
6534
6720
|
const { askAI: askAI2 } = await Promise.resolve().then(() => (init_ai2(), ai_exports));
|
|
6535
|
-
const analysis = await askAI2(signal);
|
|
6721
|
+
const analysis = await askAI2(signal, { userName });
|
|
6536
6722
|
if (typeof analysis?.quality === "number") {
|
|
6537
6723
|
const normalizedQuality = Math.round(analysis.quality);
|
|
6538
6724
|
const aiApprovedCurrentTrade = analysis?.direction === direction;
|
|
@@ -6545,6 +6731,7 @@ var enrichSignalWithAi = async ({
|
|
|
6545
6731
|
};
|
|
6546
6732
|
var enrichSignalWithMlAi = async ({
|
|
6547
6733
|
signal,
|
|
6734
|
+
userName,
|
|
6548
6735
|
symbol,
|
|
6549
6736
|
direction,
|
|
6550
6737
|
env,
|
|
@@ -6552,7 +6739,37 @@ var enrichSignalWithMlAi = async ({
|
|
|
6552
6739
|
ai
|
|
6553
6740
|
}) => {
|
|
6554
6741
|
await enrichSignalWithMl({ signal, env, ml });
|
|
6555
|
-
return enrichSignalWithAi({ signal, symbol, direction, env, ai });
|
|
6742
|
+
return enrichSignalWithAi({ signal, userName, symbol, direction, env, ai });
|
|
6743
|
+
};
|
|
6744
|
+
var applyProtectiveOrders = async ({
|
|
6745
|
+
connector,
|
|
6746
|
+
symbol,
|
|
6747
|
+
direction,
|
|
6748
|
+
qty,
|
|
6749
|
+
takeProfits,
|
|
6750
|
+
stopLossPrice
|
|
6751
|
+
}) => {
|
|
6752
|
+
if (Array.isArray(takeProfits) && takeProfits.length > 0) {
|
|
6753
|
+
const tpOk = await connector.setTakeProfits({
|
|
6754
|
+
symbol,
|
|
6755
|
+
direction,
|
|
6756
|
+
qty,
|
|
6757
|
+
takeProfits
|
|
6758
|
+
});
|
|
6759
|
+
if (!tpOk) {
|
|
6760
|
+
throw new Error("SET_TAKE_PROFITS_FAILED");
|
|
6761
|
+
}
|
|
6762
|
+
}
|
|
6763
|
+
if (typeof stopLossPrice === "number" && Number.isFinite(stopLossPrice)) {
|
|
6764
|
+
const slOk = await connector.setStopLoss({
|
|
6765
|
+
symbol,
|
|
6766
|
+
direction,
|
|
6767
|
+
stopLossPrice
|
|
6768
|
+
});
|
|
6769
|
+
if (!slOk) {
|
|
6770
|
+
throw new Error("SET_STOP_LOSS_FAILED");
|
|
6771
|
+
}
|
|
6772
|
+
}
|
|
6556
6773
|
};
|
|
6557
6774
|
var executeEntryOrder = async ({
|
|
6558
6775
|
connector,
|
|
@@ -6567,19 +6784,35 @@ var executeEntryOrder = async ({
|
|
|
6567
6784
|
beforePlaceOrder
|
|
6568
6785
|
}) => {
|
|
6569
6786
|
await beforePlaceOrder?.();
|
|
6570
|
-
const orderPlaced = await connector.placeOrder(
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
|
|
6787
|
+
const orderPlaced = await connector.placeOrder({
|
|
6788
|
+
symbol,
|
|
6789
|
+
qty,
|
|
6790
|
+
price: currentPrice,
|
|
6791
|
+
isLimit: false,
|
|
6792
|
+
timestamp,
|
|
6793
|
+
direction,
|
|
6794
|
+
signal
|
|
6795
|
+
});
|
|
6796
|
+
if (orderPlaced) {
|
|
6797
|
+
try {
|
|
6798
|
+
await applyProtectiveOrders({
|
|
6799
|
+
connector,
|
|
6800
|
+
symbol,
|
|
6801
|
+
direction,
|
|
6802
|
+
qty,
|
|
6803
|
+
takeProfits,
|
|
6804
|
+
stopLossPrice
|
|
6805
|
+
});
|
|
6806
|
+
} catch (error) {
|
|
6807
|
+
await connector.closePosition({
|
|
6808
|
+
symbol,
|
|
6809
|
+
price: currentPrice,
|
|
6810
|
+
timestamp,
|
|
6811
|
+
direction
|
|
6812
|
+
});
|
|
6813
|
+
throw error;
|
|
6814
|
+
}
|
|
6815
|
+
}
|
|
6583
6816
|
signal.orderStatus = orderPlaced ? "completed" : "failed";
|
|
6584
6817
|
signal.orderSkipReason = void 0;
|
|
6585
6818
|
const currentPosition = await connector.getPosition(symbol);
|
|
@@ -6589,11 +6822,28 @@ var executeEntryOrder = async ({
|
|
|
6589
6822
|
}
|
|
6590
6823
|
return currentPrice;
|
|
6591
6824
|
};
|
|
6825
|
+
var updatePositionProtection = async ({
|
|
6826
|
+
connector,
|
|
6827
|
+
symbol,
|
|
6828
|
+
direction,
|
|
6829
|
+
qty,
|
|
6830
|
+
takeProfits,
|
|
6831
|
+
stopLossPrice
|
|
6832
|
+
}) => {
|
|
6833
|
+
await applyProtectiveOrders({
|
|
6834
|
+
connector,
|
|
6835
|
+
symbol,
|
|
6836
|
+
direction,
|
|
6837
|
+
qty,
|
|
6838
|
+
takeProfits: takeProfits ?? [],
|
|
6839
|
+
stopLossPrice: stopLossPrice ?? null
|
|
6840
|
+
});
|
|
6841
|
+
};
|
|
6592
6842
|
|
|
6593
6843
|
// src/pine.ts
|
|
6594
6844
|
var import_node_fs = __toESM(require("fs"));
|
|
6595
6845
|
var import_node_path = __toESM(require("path"));
|
|
6596
|
-
var
|
|
6846
|
+
var loadPineScriptFile = (filePath, fallback = "") => {
|
|
6597
6847
|
const resolvedPath = String(filePath || "").trim();
|
|
6598
6848
|
if (!resolvedPath) {
|
|
6599
6849
|
return fallback;
|
|
@@ -6604,7 +6854,7 @@ var loadPineScript = (filePath, fallback = "") => {
|
|
|
6604
6854
|
return fallback;
|
|
6605
6855
|
}
|
|
6606
6856
|
};
|
|
6607
|
-
var
|
|
6857
|
+
var createPineScriptLoader = (baseDir) => {
|
|
6608
6858
|
const resolvedBaseDir = import_node_path.default.resolve(baseDir);
|
|
6609
6859
|
return (fileNameOrPath, fallback = "") => {
|
|
6610
6860
|
const rawPath = String(fileNameOrPath || "").trim();
|
|
@@ -6612,7 +6862,7 @@ var createLoadPineScript = (baseDir) => {
|
|
|
6612
6862
|
return fallback;
|
|
6613
6863
|
}
|
|
6614
6864
|
const resolvedPath = import_node_path.default.isAbsolute(rawPath) ? rawPath : import_node_path.default.resolve(resolvedBaseDir, rawPath);
|
|
6615
|
-
return
|
|
6865
|
+
return loadPineScriptFile(resolvedPath, fallback);
|
|
6616
6866
|
};
|
|
6617
6867
|
};
|
|
6618
6868
|
|
|
@@ -6691,19 +6941,32 @@ var shouldExecuteEntryDecision = ({
|
|
|
6691
6941
|
makeOrdersEnabled,
|
|
6692
6942
|
env,
|
|
6693
6943
|
signal,
|
|
6944
|
+
aiEnabled,
|
|
6694
6945
|
quality,
|
|
6695
6946
|
minAiQuality
|
|
6696
|
-
}) =>
|
|
6947
|
+
}) => {
|
|
6948
|
+
if (!makeOrdersEnabled) {
|
|
6949
|
+
return false;
|
|
6950
|
+
}
|
|
6951
|
+
if (!signal || env === "BACKTEST" || !aiEnabled) {
|
|
6952
|
+
return true;
|
|
6953
|
+
}
|
|
6954
|
+
return Number.isFinite(quality) && quality >= minAiQuality;
|
|
6955
|
+
};
|
|
6697
6956
|
var getEntrySkipReason = ({
|
|
6698
6957
|
makeOrdersEnabled,
|
|
6699
6958
|
env,
|
|
6959
|
+
aiEnabled,
|
|
6700
6960
|
quality,
|
|
6701
6961
|
minAiQuality
|
|
6702
6962
|
}) => {
|
|
6703
6963
|
if (!makeOrdersEnabled) {
|
|
6704
6964
|
return "MAKE_ORDERS_DISABLED";
|
|
6705
6965
|
}
|
|
6706
|
-
if (env !== "BACKTEST" &&
|
|
6966
|
+
if (env !== "BACKTEST" && aiEnabled && quality == null) {
|
|
6967
|
+
return "AI_QUALITY_UNAVAILABLE";
|
|
6968
|
+
}
|
|
6969
|
+
if (env !== "BACKTEST" && aiEnabled && quality != null && Number.isFinite(quality) && quality < minAiQuality) {
|
|
6707
6970
|
return `AI_QUALITY_BELOW_MIN (${quality} < ${minAiQuality})`;
|
|
6708
6971
|
}
|
|
6709
6972
|
return "ENTRY_POLICY_BLOCKED";
|
|
@@ -6874,6 +7137,33 @@ var handleExitDecision = async ({
|
|
|
6874
7137
|
}
|
|
6875
7138
|
return decision.code;
|
|
6876
7139
|
};
|
|
7140
|
+
var handleProtectDecision = async ({
|
|
7141
|
+
connector,
|
|
7142
|
+
symbol,
|
|
7143
|
+
decision,
|
|
7144
|
+
market,
|
|
7145
|
+
onRuntimeError
|
|
7146
|
+
}) => {
|
|
7147
|
+
try {
|
|
7148
|
+
await updatePositionProtection({
|
|
7149
|
+
connector,
|
|
7150
|
+
symbol,
|
|
7151
|
+
direction: decision.protectPlan.direction,
|
|
7152
|
+
takeProfits: decision.protectPlan.takeProfits ?? [],
|
|
7153
|
+
stopLossPrice: decision.protectPlan.stopLossPrice ?? null
|
|
7154
|
+
});
|
|
7155
|
+
} catch (err) {
|
|
7156
|
+
await onRuntimeError?.({
|
|
7157
|
+
stage: "protectPosition",
|
|
7158
|
+
error: err,
|
|
7159
|
+
decision,
|
|
7160
|
+
market
|
|
7161
|
+
});
|
|
7162
|
+
import_logger5.logger.error("protect position error: %s %s", symbol, err);
|
|
7163
|
+
return "ORDER_ERROR";
|
|
7164
|
+
}
|
|
7165
|
+
return decision.code;
|
|
7166
|
+
};
|
|
6877
7167
|
var executeEntryDecision = async ({
|
|
6878
7168
|
connector,
|
|
6879
7169
|
symbol,
|
|
@@ -6952,17 +7242,34 @@ var executeEntryDecision = async ({
|
|
|
6952
7242
|
return signal;
|
|
6953
7243
|
}
|
|
6954
7244
|
await beforePlaceOrder();
|
|
6955
|
-
await connector.placeOrder(
|
|
6956
|
-
|
|
7245
|
+
const orderPlaced = await connector.placeOrder({
|
|
7246
|
+
symbol,
|
|
7247
|
+
qty: decision.orderPlan.qty,
|
|
7248
|
+
price: decision.entryContext.prices.currentPrice,
|
|
7249
|
+
timestamp: decision.entryContext.timestamp,
|
|
7250
|
+
direction: decision.entryContext.direction
|
|
7251
|
+
});
|
|
7252
|
+
if (!orderPlaced) {
|
|
7253
|
+
throw new Error("PLACE_ORDER_FAILED");
|
|
7254
|
+
}
|
|
7255
|
+
try {
|
|
7256
|
+
await updatePositionProtection({
|
|
7257
|
+
connector,
|
|
6957
7258
|
symbol,
|
|
7259
|
+
direction: decision.entryContext.direction,
|
|
6958
7260
|
qty: decision.orderPlan.qty,
|
|
7261
|
+
takeProfits: decision.orderPlan.takeProfits,
|
|
7262
|
+
stopLossPrice: decision.orderPlan.stopLossPrice
|
|
7263
|
+
});
|
|
7264
|
+
} catch (error) {
|
|
7265
|
+
await connector.closePosition({
|
|
7266
|
+
symbol,
|
|
6959
7267
|
price: decision.entryContext.prices.currentPrice,
|
|
6960
7268
|
timestamp: decision.entryContext.timestamp,
|
|
6961
7269
|
direction: decision.entryContext.direction
|
|
6962
|
-
}
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
);
|
|
7270
|
+
});
|
|
7271
|
+
throw error;
|
|
7272
|
+
}
|
|
6966
7273
|
await invokeHook(
|
|
6967
7274
|
"afterPlaceOrder",
|
|
6968
7275
|
manifest?.hooks?.afterPlaceOrder,
|
|
@@ -7013,7 +7320,7 @@ var createStrategyRuntime = ({
|
|
|
7013
7320
|
}
|
|
7014
7321
|
return getStrategyManifest(name, projectRoot);
|
|
7015
7322
|
};
|
|
7016
|
-
const
|
|
7323
|
+
const loadPineScriptFile2 = createPineScriptLoader(
|
|
7017
7324
|
strategyDirectory ? import_node_path2.default.resolve(strategyDirectory) : import_node_path2.default.resolve(
|
|
7018
7325
|
projectRoot,
|
|
7019
7326
|
"packages",
|
|
@@ -7138,7 +7445,7 @@ var createStrategyRuntime = ({
|
|
|
7138
7445
|
connector,
|
|
7139
7446
|
data,
|
|
7140
7447
|
btcData,
|
|
7141
|
-
|
|
7448
|
+
loadPineScriptFile: loadPineScriptFile2,
|
|
7142
7449
|
strategyApi,
|
|
7143
7450
|
indicatorsState
|
|
7144
7451
|
});
|
|
@@ -7222,6 +7529,30 @@ var createStrategyRuntime = ({
|
|
|
7222
7529
|
}
|
|
7223
7530
|
});
|
|
7224
7531
|
}
|
|
7532
|
+
if (decision.kind === "protect") {
|
|
7533
|
+
if (!makeOrdersEnabled) {
|
|
7534
|
+
return decision.code;
|
|
7535
|
+
}
|
|
7536
|
+
return handleProtectDecision({
|
|
7537
|
+
connector,
|
|
7538
|
+
symbol,
|
|
7539
|
+
decision,
|
|
7540
|
+
market,
|
|
7541
|
+
onRuntimeError: async ({
|
|
7542
|
+
stage,
|
|
7543
|
+
error,
|
|
7544
|
+
decision: protectDecision,
|
|
7545
|
+
market: errorMarket
|
|
7546
|
+
}) => {
|
|
7547
|
+
await notifyRuntimeError({
|
|
7548
|
+
stage,
|
|
7549
|
+
error,
|
|
7550
|
+
decision: protectDecision,
|
|
7551
|
+
market: errorMarket
|
|
7552
|
+
});
|
|
7553
|
+
}
|
|
7554
|
+
});
|
|
7555
|
+
}
|
|
7225
7556
|
const runtime = resolveEntryRuntimePolicy({
|
|
7226
7557
|
decision,
|
|
7227
7558
|
config,
|
|
@@ -7274,6 +7605,7 @@ var createStrategyRuntime = ({
|
|
|
7274
7605
|
try {
|
|
7275
7606
|
quality = await enrichSignalWithAi({
|
|
7276
7607
|
signal,
|
|
7608
|
+
userName,
|
|
7277
7609
|
symbol,
|
|
7278
7610
|
direction: signal.direction,
|
|
7279
7611
|
env,
|
|
@@ -7309,6 +7641,7 @@ var createStrategyRuntime = ({
|
|
|
7309
7641
|
);
|
|
7310
7642
|
}
|
|
7311
7643
|
const minAiQuality = runtime.ai?.minQuality ?? 4;
|
|
7644
|
+
const aiEnabled = runtime.ai?.enabled !== false && runtime.ai != null;
|
|
7312
7645
|
const policy = buildHookPolicy({
|
|
7313
7646
|
quality,
|
|
7314
7647
|
makeOrdersEnabled,
|
|
@@ -7318,6 +7651,7 @@ var createStrategyRuntime = ({
|
|
|
7318
7651
|
makeOrdersEnabled,
|
|
7319
7652
|
env,
|
|
7320
7653
|
signal,
|
|
7654
|
+
aiEnabled,
|
|
7321
7655
|
quality,
|
|
7322
7656
|
minAiQuality
|
|
7323
7657
|
});
|
|
@@ -7327,6 +7661,7 @@ var createStrategyRuntime = ({
|
|
|
7327
7661
|
signal.orderSkipReason = getEntrySkipReason({
|
|
7328
7662
|
makeOrdersEnabled,
|
|
7329
7663
|
env,
|
|
7664
|
+
aiEnabled,
|
|
7330
7665
|
quality,
|
|
7331
7666
|
minAiQuality
|
|
7332
7667
|
});
|
|
@@ -7390,10 +7725,12 @@ var createCloseOppositeBeforePlaceOrderHook = ({
|
|
|
7390
7725
|
};
|
|
7391
7726
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7392
7727
|
0 && (module.exports = {
|
|
7728
|
+
DEFAULT_AI_MODEL,
|
|
7393
7729
|
MAX_AI_SERIES_POINTS,
|
|
7394
7730
|
askAI,
|
|
7395
7731
|
buildAiHumanPrompt,
|
|
7396
7732
|
buildAiPayload,
|
|
7733
|
+
buildAiPrompts,
|
|
7397
7734
|
buildAiSystemPrompt,
|
|
7398
7735
|
closeOppositePositionsBeforeOpen,
|
|
7399
7736
|
createCloseOppositeBeforePlaceOrderHook,
|
|
@@ -7401,18 +7738,24 @@ var createCloseOppositeBeforePlaceOrderHook = ({
|
|
|
7401
7738
|
enrichSignalWithAi,
|
|
7402
7739
|
enrichSignalWithMl,
|
|
7403
7740
|
enrichSignalWithMlAi,
|
|
7741
|
+
ensureAiStrategyPluginsLoaded,
|
|
7404
7742
|
ensureIndicatorPluginsLoaded,
|
|
7405
7743
|
ensureStrategyPluginsLoaded,
|
|
7406
7744
|
executeEntryOrder,
|
|
7407
7745
|
getAvailableStrategyNames,
|
|
7746
|
+
getDeterministicAiGateContext,
|
|
7747
|
+
getOpenRouterModelKwargs,
|
|
7408
7748
|
getRegisteredManifests,
|
|
7409
7749
|
getRegisteredStrategies,
|
|
7410
7750
|
getStrategyCreator,
|
|
7411
7751
|
getStrategyManifest,
|
|
7412
7752
|
isKnownStrategy,
|
|
7413
7753
|
registerStrategyEntries,
|
|
7754
|
+
resetAiRuntimeCache,
|
|
7414
7755
|
resetStrategyRegistryCache,
|
|
7415
7756
|
resolveStrategyConfig,
|
|
7757
|
+
runAiPrompt,
|
|
7758
|
+
runAiPromptLocal,
|
|
7416
7759
|
strategies,
|
|
7417
7760
|
trimSeriesDeep,
|
|
7418
7761
|
...require("@tradejs/core/strategies")
|