@tradejs/strategies 1.0.5 → 1.0.8
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/chunk-37ZWRG3W.mjs +128 -0
- package/dist/chunk-H4MHFD4B.mjs +62 -0
- package/dist/chunk-IMLNXICX.mjs +547 -0
- package/dist/chunk-QVWMBYYM.mjs +836 -0
- package/dist/chunk-SOVTOGY4.mjs +163 -0
- package/dist/chunk-TDUTYEGH.mjs +797 -0
- package/dist/chunk-UK4YHD2E.mjs +683 -0
- package/dist/index.d.mts +325 -4
- package/dist/index.d.ts +325 -4
- package/dist/index.js +5689 -1195
- package/dist/index.mjs +61 -14
- package/dist/{strategy-ZVNTA6UR.mjs → strategy-ABIO65CR.mjs} +3 -46
- package/dist/strategy-D7H5J3C4.mjs +348 -0
- package/dist/strategy-HQIPCUOY.mjs +399 -0
- package/dist/{strategy-Y4SOK6FF.mjs → strategy-JQIJILHQ.mjs} +28 -109
- package/dist/strategy-QEIPAPY4.mjs +373 -0
- package/dist/strategy-WYN4FZ5S.mjs +613 -0
- package/dist/{strategy-UHRWSGZC.mjs → strategy-XTUKPYPM.mjs} +484 -128
- package/package.json +5 -5
- package/dist/chunk-3PN7ZSJJ.mjs +0 -27
- package/dist/chunk-MVIV5ZII.mjs +0 -137
- package/dist/chunk-RDK2JK3K.mjs +0 -28
- package/dist/chunk-RYEPHOGL.mjs +0 -28
- package/dist/chunk-ULLCAH5C.mjs +0 -67
- package/dist/strategy-M3BRWDRR.mjs +0 -377
- package/dist/strategy-UZBWST3G.mjs +0 -156
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// src/TrendShift/adapters/ai.ts
|
|
2
|
+
import { mapAiRuntimeFromConfig } from "@tradejs/core/strategies";
|
|
3
|
+
var getTrendShiftContext = (payload) => {
|
|
4
|
+
const additional = payload.additionalIndicators;
|
|
5
|
+
const raw = additional?.trendShiftContext ?? {};
|
|
6
|
+
const hardBlockReasons = [];
|
|
7
|
+
if (!raw.confirmedFlip) {
|
|
8
|
+
hardBlockReasons.push("unconfirmed_flip");
|
|
9
|
+
}
|
|
10
|
+
if (!raw.flipDistanceOk) {
|
|
11
|
+
hardBlockReasons.push("weak_flip_distance");
|
|
12
|
+
}
|
|
13
|
+
if (raw.coinBiasAligned === false) {
|
|
14
|
+
hardBlockReasons.push("coin_bias_conflict");
|
|
15
|
+
}
|
|
16
|
+
const slopeAbs = Math.abs(raw.avgSlopePct ?? 0);
|
|
17
|
+
const distanceAtrRatio = raw.distanceAtrRatio ?? 0;
|
|
18
|
+
const closeVsAvgPctAbs = Math.abs(raw.closeVsAvgPct ?? 0);
|
|
19
|
+
let deterministicQuality = 3;
|
|
20
|
+
if (hardBlockReasons.length > 0) {
|
|
21
|
+
deterministicQuality = raw.confirmedFlip ? 2 : 1;
|
|
22
|
+
} else if (distanceAtrRatio >= 0.8 && slopeAbs >= 0.09 && closeVsAvgPctAbs >= 0.12) {
|
|
23
|
+
deterministicQuality = 5;
|
|
24
|
+
} else if (distanceAtrRatio >= 0.45 && slopeAbs >= 0.04 && closeVsAvgPctAbs >= 0.05) {
|
|
25
|
+
deterministicQuality = 4;
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
...raw,
|
|
29
|
+
deterministicQuality,
|
|
30
|
+
approvalAllowedNow: deterministicQuality >= 4,
|
|
31
|
+
hardBlockReasons
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
var reasonText = (reason) => {
|
|
35
|
+
switch (reason) {
|
|
36
|
+
case "unconfirmed_flip":
|
|
37
|
+
return "the internal flip is not confirmed yet";
|
|
38
|
+
case "weak_flip_distance":
|
|
39
|
+
return "price moved away from the adaptive average too weakly";
|
|
40
|
+
case "coin_bias_conflict":
|
|
41
|
+
return "coin MA bias conflicts with the flip direction";
|
|
42
|
+
default:
|
|
43
|
+
return reason;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var trendShiftAiAdapter = {
|
|
47
|
+
buildPayload: ({ signal, basePayload }) => ({
|
|
48
|
+
...basePayload,
|
|
49
|
+
additionalIndicators: {
|
|
50
|
+
...basePayload.additionalIndicators,
|
|
51
|
+
trendShiftContext: signal.additionalIndicators?.trendShiftContext
|
|
52
|
+
}
|
|
53
|
+
}),
|
|
54
|
+
postProcessAnalysis: ({ payload, analysis }) => {
|
|
55
|
+
const context = getTrendShiftContext(payload);
|
|
56
|
+
const requestedDirection = analysis.direction === "LONG" || analysis.direction === "SHORT" ? analysis.direction : context.signalDirection;
|
|
57
|
+
if (context.approvalAllowedNow === true && requestedDirection != null) {
|
|
58
|
+
return {
|
|
59
|
+
...analysis,
|
|
60
|
+
direction: requestedDirection,
|
|
61
|
+
quality: context.deterministicQuality,
|
|
62
|
+
approved: true
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
...analysis,
|
|
67
|
+
direction: null,
|
|
68
|
+
quality: context.deterministicQuality,
|
|
69
|
+
approved: false,
|
|
70
|
+
rejectReason: context.hardBlockReasons.length > 0 ? context.hardBlockReasons.map(reasonText).join("; ") : "the flip still does not look strong enough for live approval"
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
buildHumanPromptAddon: ({ payload }) => {
|
|
74
|
+
const context = getTrendShiftContext(payload);
|
|
75
|
+
return `
|
|
76
|
+
Additional TrendShift context:
|
|
77
|
+
- signalDirection=${context.signalDirection ?? "n/a"}
|
|
78
|
+
- confirmedFlip=${String(context.confirmedFlip)}
|
|
79
|
+
- bullFlip=${String(context.bullFlip)}
|
|
80
|
+
- bearFlip=${String(context.bearFlip)}
|
|
81
|
+
- flipDistanceOk=${String(context.flipDistanceOk)}
|
|
82
|
+
- closeVsAvgPct=${String(context.closeVsAvgPct ?? "n/a")}
|
|
83
|
+
- bandWidthPct=${String(context.bandWidthPct ?? "n/a")}
|
|
84
|
+
- avgSlopePct=${String(context.avgSlopePct ?? "n/a")}
|
|
85
|
+
- distanceAtrRatio=${String(context.distanceAtrRatio ?? "n/a")}
|
|
86
|
+
- coinBias=${context.coinBias ?? "n/a"}
|
|
87
|
+
- coinBiasAligned=${String(context.coinBiasAligned)}
|
|
88
|
+
- deterministicQuality=${context.deterministicQuality}
|
|
89
|
+
- approvalAllowedNow=${context.approvalAllowedNow}
|
|
90
|
+
- hardBlockReasons=${JSON.stringify(context.hardBlockReasons)}
|
|
91
|
+
|
|
92
|
+
Interpretation rules for TrendShift:
|
|
93
|
+
- This is a trend-state flip strategy, not a forecast of future impulse.
|
|
94
|
+
- If approvalAllowedNow=false, do not describe the signal as a fully confirmed live entry.
|
|
95
|
+
- If hardBlockReasons is not empty, explain exactly what is still missing for confirmation.
|
|
96
|
+
`.trim();
|
|
97
|
+
},
|
|
98
|
+
mapEntryRuntimeFromConfig: (config2) => mapAiRuntimeFromConfig(
|
|
99
|
+
config2
|
|
100
|
+
)
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// src/TrendShift/manifest.ts
|
|
104
|
+
var trendShiftManifest = {
|
|
105
|
+
name: "TrendShift",
|
|
106
|
+
aiAdapter: trendShiftAiAdapter
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// src/TrendShift/config.ts
|
|
110
|
+
var config = {
|
|
111
|
+
ENV: "BACKTEST",
|
|
112
|
+
INTERVAL: "15",
|
|
113
|
+
MAKE_ORDERS: true,
|
|
114
|
+
CLOSE_OPPOSITE_POSITIONS: false,
|
|
115
|
+
BACKTEST_PRICE_MODE: "mid",
|
|
116
|
+
AI_ENABLED: false,
|
|
117
|
+
AI_MODE: "llm",
|
|
118
|
+
ML_ENABLED: false,
|
|
119
|
+
ML_THRESHOLD: 0.1,
|
|
120
|
+
MIN_AI_QUALITY: 3,
|
|
121
|
+
FEE_PERCENT: 5e-3,
|
|
122
|
+
MAX_LOSS_VALUE: 10,
|
|
123
|
+
MA_FAST: 14,
|
|
124
|
+
MA_MEDIUM: 49,
|
|
125
|
+
MA_SLOW: 50,
|
|
126
|
+
OBV_SMA: 10,
|
|
127
|
+
ATR: 14,
|
|
128
|
+
ATR_PCT_SHORT: 7,
|
|
129
|
+
ATR_PCT_LONG: 30,
|
|
130
|
+
BB: 20,
|
|
131
|
+
BB_STD: 2,
|
|
132
|
+
MACD_FAST: 12,
|
|
133
|
+
MACD_SLOW: 26,
|
|
134
|
+
MACD_SIGNAL: 9,
|
|
135
|
+
TRENDSHIFT_MULTIPLICATIVE_FACTOR: 4,
|
|
136
|
+
TRENDSHIFT_SLOPE: 12,
|
|
137
|
+
TRENDSHIFT_ATR_LENGTH: 150,
|
|
138
|
+
TRENDSHIFT_WIDTH_PCT: 75,
|
|
139
|
+
TRENDSHIFT_CONFIRM_FLIP_WITH_CLOSE: true,
|
|
140
|
+
TRENDSHIFT_MIN_FLIP_DISTANCE_ATR: 0.15,
|
|
141
|
+
TRENDSHIFT_EXIT_ON_OPPOSITE_FLIP: true,
|
|
142
|
+
TRENDSHIFT_MAX_FIGURE_POINTS: 180,
|
|
143
|
+
LONG: {
|
|
144
|
+
enable: true,
|
|
145
|
+
direction: "LONG",
|
|
146
|
+
TP: 2.8,
|
|
147
|
+
SL: 1.1,
|
|
148
|
+
minRiskRatio: 1.6
|
|
149
|
+
},
|
|
150
|
+
SHORT: {
|
|
151
|
+
enable: true,
|
|
152
|
+
direction: "SHORT",
|
|
153
|
+
TP: 2.8,
|
|
154
|
+
SL: 1.1,
|
|
155
|
+
minRiskRatio: 1.6
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export {
|
|
160
|
+
trendShiftAiAdapter,
|
|
161
|
+
trendShiftManifest,
|
|
162
|
+
config
|
|
163
|
+
};
|