@tradejs/node 3.0.0 → 3.1.0
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/README.md +2 -0
- package/dist/ai.d.mts +26 -4
- package/dist/ai.d.ts +26 -4
- package/dist/ai.js +161 -165
- package/dist/ai.mjs +3 -1
- package/dist/backtest.js +496 -188
- package/dist/backtest.mjs +3 -3
- package/dist/chunk-3TWULKHV.mjs +595 -0
- package/dist/chunk-FB5NUEOQ.mjs +295 -0
- package/dist/{chunk-VRXU4E4O.mjs → chunk-KOQSLFT2.mjs} +169 -169
- package/dist/chunk-LAJ7NA3Q.mjs +377 -0
- package/dist/{chunk-OGAWBO3Z.mjs → chunk-MKLTJQLY.mjs} +1 -1
- package/dist/cli.js +150 -161
- package/dist/cli.mjs +1 -1
- package/dist/connectors.d.mts +5 -2
- package/dist/connectors.d.ts +5 -2
- package/dist/connectors.js +329 -8
- package/dist/connectors.mjs +5 -1
- package/dist/registry.d.mts +2 -1
- package/dist/registry.d.ts +2 -1
- package/dist/registry.js +157 -161
- package/dist/registry.mjs +4 -2
- package/dist/runtimeDashboard.d.mts +12 -0
- package/dist/runtimeDashboard.d.ts +12 -0
- package/dist/runtimeDashboard.js +8433 -0
- package/dist/runtimeDashboard.mjs +955 -0
- package/dist/runtimeTrades.d.mts +31 -0
- package/dist/runtimeTrades.d.ts +31 -0
- package/dist/runtimeTrades.js +321 -0
- package/dist/runtimeTrades.mjs +11 -0
- package/dist/strategies.d.mts +2 -2
- package/dist/strategies.d.ts +2 -2
- package/dist/strategies.js +168 -165
- package/dist/strategies.mjs +13 -372
- package/package.json +18 -5
- package/dist/chunk-V3YMKE4I.mjs +0 -271
package/dist/strategies.mjs
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
closeOppositePositionsBeforeOpen,
|
|
3
|
+
createCloseAllOnGlobalProfitBeforeSignalsHook,
|
|
4
|
+
createCloseOppositeBeforePlaceOrderHook,
|
|
5
|
+
createMoveStopToBreakEvenAfterCoreDecisionHook,
|
|
6
|
+
createMoveStopToBreakEvenOnBarHook
|
|
7
|
+
} from "./chunk-LAJ7NA3Q.mjs";
|
|
1
8
|
import {
|
|
2
9
|
BINANCE_BREADTH_UNIVERSE_KEYS,
|
|
3
10
|
buildBinanceBreadthUniverseSnapshot,
|
|
@@ -22,7 +29,7 @@ import {
|
|
|
22
29
|
resolveHyperliquidPerpFromSignalSymbol,
|
|
23
30
|
resolveStrategyConfig,
|
|
24
31
|
validateEntryProtectionAtArrival
|
|
25
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-MKLTJQLY.mjs";
|
|
26
33
|
import {
|
|
27
34
|
DEFAULT_AI_MODEL,
|
|
28
35
|
MAX_AI_SERIES_POINTS,
|
|
@@ -40,7 +47,9 @@ import {
|
|
|
40
47
|
getRegisteredManifests,
|
|
41
48
|
getRegisteredStrategies,
|
|
42
49
|
getStrategyCreator,
|
|
50
|
+
getStrategyDefaults,
|
|
43
51
|
getStrategyManifest,
|
|
52
|
+
invokeAiChat,
|
|
44
53
|
isKnownStrategy,
|
|
45
54
|
registerStrategyEntries,
|
|
46
55
|
resetAiRuntimeCache,
|
|
@@ -49,379 +58,9 @@ import {
|
|
|
49
58
|
runAiPromptLocal,
|
|
50
59
|
strategies,
|
|
51
60
|
trimSeriesDeep
|
|
52
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-KOQSLFT2.mjs";
|
|
53
62
|
import "./chunk-WS5DYEVZ.mjs";
|
|
54
63
|
import "./chunk-Y6FXYEAI.mjs";
|
|
55
|
-
|
|
56
|
-
// src/strategies.ts
|
|
57
|
-
export * from "@tradejs/core/strategies";
|
|
58
|
-
|
|
59
|
-
// src/strategyHooks/closeOppositePositionsBeforeOpen.ts
|
|
60
|
-
import _ from "lodash";
|
|
61
|
-
import { logger } from "@tradejs/infra/logger";
|
|
62
|
-
var closeOppositePositionsBeforeOpen = async ({
|
|
63
|
-
connector,
|
|
64
|
-
entryContext
|
|
65
|
-
}) => {
|
|
66
|
-
const {
|
|
67
|
-
symbol: currentSymbol,
|
|
68
|
-
direction: currentDirection,
|
|
69
|
-
timestamp,
|
|
70
|
-
prices,
|
|
71
|
-
strategy: strategyName
|
|
72
|
-
} = entryContext;
|
|
73
|
-
const price = prices.currentPrice;
|
|
74
|
-
try {
|
|
75
|
-
logger.log(
|
|
76
|
-
"info",
|
|
77
|
-
"[%s] checking open positions before open: %s %s",
|
|
78
|
-
strategyName,
|
|
79
|
-
currentSymbol,
|
|
80
|
-
currentDirection
|
|
81
|
-
);
|
|
82
|
-
const positions = await connector.getPositions();
|
|
83
|
-
const openPositions = (positions || []).filter(
|
|
84
|
-
(item) => item && Number(item.qty) > 0
|
|
85
|
-
);
|
|
86
|
-
logger.log(
|
|
87
|
-
"info",
|
|
88
|
-
"[%s] open positions found: %s",
|
|
89
|
-
strategyName,
|
|
90
|
-
openPositions.length
|
|
91
|
-
);
|
|
92
|
-
const oppositePositions = openPositions.filter(
|
|
93
|
-
(item) => item.symbol !== currentSymbol && item.direction !== currentDirection
|
|
94
|
-
);
|
|
95
|
-
if (_.isEmpty(oppositePositions)) {
|
|
96
|
-
logger.log(
|
|
97
|
-
"info",
|
|
98
|
-
"[%s] no opposite positions to close before open: %s",
|
|
99
|
-
strategyName,
|
|
100
|
-
currentSymbol
|
|
101
|
-
);
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
for (const position of oppositePositions) {
|
|
105
|
-
logger.log(
|
|
106
|
-
"info",
|
|
107
|
-
"[%s] closing opposite position: %s %s qty=%s",
|
|
108
|
-
strategyName,
|
|
109
|
-
position.symbol,
|
|
110
|
-
position.direction,
|
|
111
|
-
position.qty
|
|
112
|
-
);
|
|
113
|
-
try {
|
|
114
|
-
await connector.closePosition({
|
|
115
|
-
symbol: position.symbol,
|
|
116
|
-
price,
|
|
117
|
-
timestamp,
|
|
118
|
-
direction: position.direction
|
|
119
|
-
});
|
|
120
|
-
logger.log(
|
|
121
|
-
"info",
|
|
122
|
-
"[%s] opposite position closed: %s",
|
|
123
|
-
strategyName,
|
|
124
|
-
position.symbol
|
|
125
|
-
);
|
|
126
|
-
} catch (err) {
|
|
127
|
-
logger.log(
|
|
128
|
-
"error",
|
|
129
|
-
"[%s] failed to close opposite position: %s %s",
|
|
130
|
-
strategyName,
|
|
131
|
-
position.symbol,
|
|
132
|
-
err
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
} catch (err) {
|
|
137
|
-
logger.log(
|
|
138
|
-
"error",
|
|
139
|
-
"[%s] failed to load open positions before open: %s %s",
|
|
140
|
-
strategyName,
|
|
141
|
-
currentSymbol,
|
|
142
|
-
err
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
var createCloseOppositeBeforePlaceOrderHook = ({
|
|
147
|
-
isEnabled
|
|
148
|
-
}) => {
|
|
149
|
-
return async ({ ctx, entry }) => {
|
|
150
|
-
if (ctx.env === "BACKTEST") {
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
if (!isEnabled(ctx.strategyConfig)) {
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
await closeOppositePositionsBeforeOpen({
|
|
157
|
-
connector: ctx.connector,
|
|
158
|
-
entryContext: entry.context
|
|
159
|
-
});
|
|
160
|
-
};
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
// src/strategyHooks/shared.ts
|
|
164
|
-
var DEFAULT_BREAK_EVEN_TRIGGER_RISK_MULTIPLIER = 0.5;
|
|
165
|
-
var DEFAULT_BREAK_EVEN_STOP_PROFIT_MULTIPLIER = 0;
|
|
166
|
-
var DEFAULT_GLOBAL_UNREALIZED_PNL_TRIGGER_RISK_MULTIPLIER = 4;
|
|
167
|
-
var GLOBAL_UNREALIZED_PNL_CLOSE_ALL_CODE = "GLOBAL_UNREALIZED_PNL_TARGET_REACHED_CLOSE_ALL";
|
|
168
|
-
var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
169
|
-
var isOpenPosition = (position) => Boolean(
|
|
170
|
-
position && isFiniteNumber(position.price) && isFiniteNumber(position.qty) && position.qty > 0 && (position.direction === "LONG" || position.direction === "SHORT")
|
|
171
|
-
);
|
|
172
|
-
var isOpenPositionPnlSnapshot = (position) => Boolean(
|
|
173
|
-
isOpenPosition(position) && isFiniteNumber(position?.currentPrice) && isFiniteNumber(position?.unrealizedPnl)
|
|
174
|
-
);
|
|
175
|
-
var getStrategyMaxLossValue = (strategyConfig) => {
|
|
176
|
-
const maxLossValue = Number(strategyConfig?.MAX_LOSS_VALUE ?? Number.NaN);
|
|
177
|
-
return Number.isFinite(maxLossValue) && maxLossValue > 0 ? maxLossValue : null;
|
|
178
|
-
};
|
|
179
|
-
var getPositionStopLossPrice = (position) => {
|
|
180
|
-
if (!position || typeof position !== "object") {
|
|
181
|
-
return null;
|
|
182
|
-
}
|
|
183
|
-
const slPrice = Number(
|
|
184
|
-
position.slPrice ?? Number.NaN
|
|
185
|
-
);
|
|
186
|
-
if (Number.isFinite(slPrice)) {
|
|
187
|
-
return slPrice;
|
|
188
|
-
}
|
|
189
|
-
const signalStopLossPrice = Number(
|
|
190
|
-
position.signal?.prices?.stopLossPrice ?? Number.NaN
|
|
191
|
-
);
|
|
192
|
-
return Number.isFinite(signalStopLossPrice) ? signalStopLossPrice : null;
|
|
193
|
-
};
|
|
194
|
-
var getPositionTakeProfitPrice = (position) => {
|
|
195
|
-
if (!position || typeof position !== "object") {
|
|
196
|
-
return null;
|
|
197
|
-
}
|
|
198
|
-
const directTakeProfitPrice = Number(
|
|
199
|
-
position.tpPrice ?? position.takeProfitPrice ?? Number.NaN
|
|
200
|
-
);
|
|
201
|
-
if (Number.isFinite(directTakeProfitPrice)) {
|
|
202
|
-
return directTakeProfitPrice;
|
|
203
|
-
}
|
|
204
|
-
const signalTakeProfitPrice = Number(
|
|
205
|
-
position.signal?.prices?.takeProfitPrice ?? Number.NaN
|
|
206
|
-
);
|
|
207
|
-
return Number.isFinite(signalTakeProfitPrice) ? signalTakeProfitPrice : null;
|
|
208
|
-
};
|
|
209
|
-
var getBreakEvenStopPrice = ({
|
|
210
|
-
direction,
|
|
211
|
-
entryPrice,
|
|
212
|
-
takeProfitPrice,
|
|
213
|
-
stopProfitMultiplier
|
|
214
|
-
}) => {
|
|
215
|
-
if (!Number.isFinite(entryPrice)) {
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
218
|
-
const normalizedStopProfitMultiplier = Number.isFinite(stopProfitMultiplier) ? Math.min(Math.max(stopProfitMultiplier, 0), 1) : DEFAULT_BREAK_EVEN_STOP_PROFIT_MULTIPLIER;
|
|
219
|
-
if (takeProfitPrice == null || !Number.isFinite(takeProfitPrice) || direction === "LONG" && takeProfitPrice <= entryPrice || direction === "SHORT" && takeProfitPrice >= entryPrice) {
|
|
220
|
-
return entryPrice;
|
|
221
|
-
}
|
|
222
|
-
const distanceToTakeProfit = takeProfitPrice - entryPrice;
|
|
223
|
-
return entryPrice + distanceToTakeProfit * normalizedStopProfitMultiplier;
|
|
224
|
-
};
|
|
225
|
-
var getFavorableMovePct = ({
|
|
226
|
-
direction,
|
|
227
|
-
entryPrice,
|
|
228
|
-
currentPrice
|
|
229
|
-
}) => {
|
|
230
|
-
if (!Number.isFinite(entryPrice) || !Number.isFinite(currentPrice) || entryPrice <= 0) {
|
|
231
|
-
return null;
|
|
232
|
-
}
|
|
233
|
-
return direction === "LONG" ? (currentPrice - entryPrice) / entryPrice * 100 : (entryPrice - currentPrice) / entryPrice * 100;
|
|
234
|
-
};
|
|
235
|
-
var getPositionRiskPct = ({
|
|
236
|
-
direction,
|
|
237
|
-
entryPrice,
|
|
238
|
-
stopLossPrice
|
|
239
|
-
}) => {
|
|
240
|
-
if (stopLossPrice == null || !Number.isFinite(entryPrice) || !Number.isFinite(stopLossPrice) || entryPrice <= 0) {
|
|
241
|
-
return null;
|
|
242
|
-
}
|
|
243
|
-
return direction === "LONG" ? (entryPrice - stopLossPrice) / entryPrice * 100 : (stopLossPrice - entryPrice) / entryPrice * 100;
|
|
244
|
-
};
|
|
245
|
-
var isBreakEvenStopAlreadyApplied = ({
|
|
246
|
-
direction,
|
|
247
|
-
entryPrice,
|
|
248
|
-
stopLossPrice
|
|
249
|
-
}) => {
|
|
250
|
-
if (stopLossPrice == null || !Number.isFinite(entryPrice) || !Number.isFinite(stopLossPrice)) {
|
|
251
|
-
return false;
|
|
252
|
-
}
|
|
253
|
-
return direction === "LONG" ? stopLossPrice >= entryPrice : stopLossPrice <= entryPrice;
|
|
254
|
-
};
|
|
255
|
-
var getConfiguredDirectionRiskPct = ({
|
|
256
|
-
strategyConfig,
|
|
257
|
-
direction
|
|
258
|
-
}) => {
|
|
259
|
-
if (!strategyConfig || typeof strategyConfig !== "object") {
|
|
260
|
-
return null;
|
|
261
|
-
}
|
|
262
|
-
const directSideConfig = strategyConfig[direction];
|
|
263
|
-
const directSideRiskPct = Number(directSideConfig?.SL ?? Number.NaN);
|
|
264
|
-
if (Number.isFinite(directSideRiskPct)) {
|
|
265
|
-
return directSideRiskPct;
|
|
266
|
-
}
|
|
267
|
-
for (const candidate of Object.values(strategyConfig)) {
|
|
268
|
-
if (!candidate || typeof candidate !== "object") {
|
|
269
|
-
continue;
|
|
270
|
-
}
|
|
271
|
-
const candidateDirection = candidate.direction;
|
|
272
|
-
const candidateRiskPct = Number(
|
|
273
|
-
candidate.SL ?? Number.NaN
|
|
274
|
-
);
|
|
275
|
-
if (candidateDirection === direction && Number.isFinite(candidateRiskPct)) {
|
|
276
|
-
return candidateRiskPct;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
return null;
|
|
280
|
-
};
|
|
281
|
-
var toStrategyCodePrefix = (strategyName) => strategyName === "TrendLine" ? "TRENDLINE" : strategyName.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").toUpperCase();
|
|
282
|
-
|
|
283
|
-
// src/strategyHooks/moveStopToBreakEvenAfterCoreDecision.ts
|
|
284
|
-
var createMoveStopToBreakEvenOnBarHook = ({
|
|
285
|
-
isEnabled = () => true,
|
|
286
|
-
triggerRiskMultiplier = DEFAULT_BREAK_EVEN_TRIGGER_RISK_MULTIPLIER,
|
|
287
|
-
stopProfitMultiplier = DEFAULT_BREAK_EVEN_STOP_PROFIT_MULTIPLIER
|
|
288
|
-
} = {}) => {
|
|
289
|
-
return async ({ ctx, market }) => {
|
|
290
|
-
if (!isEnabled(ctx.strategyConfig)) {
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
const currentPosition = await ctx.connector.getPosition(ctx.symbol);
|
|
294
|
-
if (!isOpenPosition(currentPosition)) {
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
const currentPrice = Number(market.candle.close ?? Number.NaN);
|
|
298
|
-
if (!Number.isFinite(currentPrice)) {
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
const currentStopLossPrice = getPositionStopLossPrice(currentPosition);
|
|
302
|
-
if (isBreakEvenStopAlreadyApplied({
|
|
303
|
-
direction: currentPosition.direction,
|
|
304
|
-
entryPrice: currentPosition.price,
|
|
305
|
-
stopLossPrice: currentStopLossPrice
|
|
306
|
-
})) {
|
|
307
|
-
return;
|
|
308
|
-
}
|
|
309
|
-
const favorableMovePct = getFavorableMovePct({
|
|
310
|
-
direction: currentPosition.direction,
|
|
311
|
-
entryPrice: currentPosition.price,
|
|
312
|
-
currentPrice
|
|
313
|
-
});
|
|
314
|
-
const currentPositionRiskPct = getPositionRiskPct({
|
|
315
|
-
direction: currentPosition.direction,
|
|
316
|
-
entryPrice: currentPosition.price,
|
|
317
|
-
stopLossPrice: currentStopLossPrice
|
|
318
|
-
});
|
|
319
|
-
const configuredRiskPct = getConfiguredDirectionRiskPct({
|
|
320
|
-
strategyConfig: ctx.strategyConfig,
|
|
321
|
-
direction: currentPosition.direction
|
|
322
|
-
});
|
|
323
|
-
const triggerRiskPct = currentPositionRiskPct ?? configuredRiskPct;
|
|
324
|
-
if (favorableMovePct == null || triggerRiskPct == null || favorableMovePct < triggerRiskPct * triggerRiskMultiplier) {
|
|
325
|
-
return;
|
|
326
|
-
}
|
|
327
|
-
const stopLossPrice = getBreakEvenStopPrice({
|
|
328
|
-
direction: currentPosition.direction,
|
|
329
|
-
entryPrice: currentPosition.price,
|
|
330
|
-
takeProfitPrice: getPositionTakeProfitPrice(currentPosition),
|
|
331
|
-
stopProfitMultiplier
|
|
332
|
-
});
|
|
333
|
-
if (stopLossPrice == null) {
|
|
334
|
-
return;
|
|
335
|
-
}
|
|
336
|
-
return {
|
|
337
|
-
kind: "protect",
|
|
338
|
-
code: `${toStrategyCodePrefix(ctx.strategyName)}_MOVE_STOP_TO_BREAK_EVEN`,
|
|
339
|
-
protectPlan: {
|
|
340
|
-
direction: currentPosition.direction,
|
|
341
|
-
stopLossPrice
|
|
342
|
-
}
|
|
343
|
-
};
|
|
344
|
-
};
|
|
345
|
-
};
|
|
346
|
-
var createMoveStopToBreakEvenAfterCoreDecisionHook = createMoveStopToBreakEvenOnBarHook;
|
|
347
|
-
|
|
348
|
-
// src/signalsHooks/closeAllPositionsOnGlobalProfitBeforeSignals.ts
|
|
349
|
-
import { logger as logger2 } from "@tradejs/infra/logger";
|
|
350
|
-
var createCloseAllOnGlobalProfitBeforeSignalsHook = ({
|
|
351
|
-
getStrategyDefaultConfig = () => void 0,
|
|
352
|
-
profitRiskMultiplier = DEFAULT_GLOBAL_UNREALIZED_PNL_TRIGGER_RISK_MULTIPLIER
|
|
353
|
-
} = {}) => {
|
|
354
|
-
return async ({ connector, runtimeStrategies }) => {
|
|
355
|
-
if (typeof connector.getOpenPositionPnl !== "function") {
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
const openPositions = (await connector.getOpenPositionPnl()).filter(
|
|
359
|
-
isOpenPositionPnlSnapshot
|
|
360
|
-
);
|
|
361
|
-
if (!openPositions.length) {
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
const totalUnrealizedPnl = openPositions.reduce(
|
|
365
|
-
(sum, position) => sum + position.unrealizedPnl,
|
|
366
|
-
0
|
|
367
|
-
);
|
|
368
|
-
if (!Number.isFinite(totalUnrealizedPnl) || totalUnrealizedPnl <= 0) {
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
const maxLossValues = runtimeStrategies.flatMap(
|
|
372
|
-
({ strategyName, strategyConfig }) => {
|
|
373
|
-
const maxLossValue = getStrategyMaxLossValue({
|
|
374
|
-
...getStrategyDefaultConfig(strategyName) ?? {},
|
|
375
|
-
...strategyConfig ?? {}
|
|
376
|
-
});
|
|
377
|
-
return maxLossValue == null ? [] : [maxLossValue];
|
|
378
|
-
}
|
|
379
|
-
);
|
|
380
|
-
if (!maxLossValues.length) {
|
|
381
|
-
return;
|
|
382
|
-
}
|
|
383
|
-
const averageMaxLossValue = maxLossValues.reduce((sum, value) => sum + value, 0) / maxLossValues.length;
|
|
384
|
-
const unrealizedPnlThreshold = averageMaxLossValue * profitRiskMultiplier;
|
|
385
|
-
if (!Number.isFinite(unrealizedPnlThreshold) || unrealizedPnlThreshold <= 0 || totalUnrealizedPnl < unrealizedPnlThreshold) {
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
388
|
-
logger2.info(
|
|
389
|
-
"closing all positions before signals by global unrealized pnl threshold: totalPnl=%s threshold=%s positions=%s",
|
|
390
|
-
totalUnrealizedPnl,
|
|
391
|
-
unrealizedPnlThreshold,
|
|
392
|
-
openPositions.length
|
|
393
|
-
);
|
|
394
|
-
const closeTimestamp = Date.now();
|
|
395
|
-
const closeResults = await Promise.allSettled(
|
|
396
|
-
openPositions.map(
|
|
397
|
-
(position) => connector.closePosition({
|
|
398
|
-
symbol: position.symbol,
|
|
399
|
-
direction: position.direction,
|
|
400
|
-
price: position.currentPrice,
|
|
401
|
-
timestamp: closeTimestamp
|
|
402
|
-
})
|
|
403
|
-
)
|
|
404
|
-
);
|
|
405
|
-
const failedClosures = closeResults.flatMap((result, index) => {
|
|
406
|
-
if (result.status === "fulfilled" && result.value === true) {
|
|
407
|
-
return [];
|
|
408
|
-
}
|
|
409
|
-
return [
|
|
410
|
-
`${openPositions[index]?.symbol}:${openPositions[index]?.direction ?? "UNKNOWN"}`
|
|
411
|
-
];
|
|
412
|
-
});
|
|
413
|
-
if (failedClosures.length) {
|
|
414
|
-
logger2.warn(
|
|
415
|
-
"close-all before signals hook could not confirm closures for %s",
|
|
416
|
-
failedClosures.join(", ")
|
|
417
|
-
);
|
|
418
|
-
}
|
|
419
|
-
return {
|
|
420
|
-
abort: true,
|
|
421
|
-
reason: GLOBAL_UNREALIZED_PNL_CLOSE_ALL_CODE
|
|
422
|
-
};
|
|
423
|
-
};
|
|
424
|
-
};
|
|
425
64
|
export {
|
|
426
65
|
BINANCE_BREADTH_UNIVERSE_KEYS,
|
|
427
66
|
DEFAULT_AI_MODEL,
|
|
@@ -462,7 +101,9 @@ export {
|
|
|
462
101
|
getRegisteredManifests,
|
|
463
102
|
getRegisteredStrategies,
|
|
464
103
|
getStrategyCreator,
|
|
104
|
+
getStrategyDefaults,
|
|
465
105
|
getStrategyManifest,
|
|
106
|
+
invokeAiChat,
|
|
466
107
|
isKnownStrategy,
|
|
467
108
|
isTrackedHyperliquidPerp,
|
|
468
109
|
isTrackedHyperliquidWhale,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tradejs/node",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Node-only runtime for the TradeJS TypeScript framework: strategies, backtests, Pine strategy loading, and plugin registries.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tradejs",
|
|
@@ -58,6 +58,16 @@
|
|
|
58
58
|
"import": "./dist/registry.mjs",
|
|
59
59
|
"require": "./dist/registry.js"
|
|
60
60
|
},
|
|
61
|
+
"./runtimeTrades": {
|
|
62
|
+
"types": "./dist/runtimeTrades.d.ts",
|
|
63
|
+
"import": "./dist/runtimeTrades.mjs",
|
|
64
|
+
"require": "./dist/runtimeTrades.js"
|
|
65
|
+
},
|
|
66
|
+
"./runtimeDashboard": {
|
|
67
|
+
"types": "./dist/runtimeDashboard.d.ts",
|
|
68
|
+
"import": "./dist/runtimeDashboard.mjs",
|
|
69
|
+
"require": "./dist/runtimeDashboard.js"
|
|
70
|
+
},
|
|
61
71
|
"./strategies": {
|
|
62
72
|
"types": "./dist/strategies.d.ts",
|
|
63
73
|
"import": "./dist/strategies.mjs",
|
|
@@ -67,9 +77,9 @@
|
|
|
67
77
|
"dependencies": {
|
|
68
78
|
"@langchain/core": "^1.2.3",
|
|
69
79
|
"@langchain/openai": "^1.5.5",
|
|
70
|
-
"@tradejs/core": "^3.
|
|
71
|
-
"@tradejs/infra": "^3.
|
|
72
|
-
"@tradejs/types": "^3.
|
|
80
|
+
"@tradejs/core": "^3.1.0",
|
|
81
|
+
"@tradejs/infra": "^3.1.0",
|
|
82
|
+
"@tradejs/types": "^3.1.0",
|
|
73
83
|
"chalk": "4.1.2",
|
|
74
84
|
"ioredis": "5.11.1",
|
|
75
85
|
"lodash": "^4.18.1",
|
|
@@ -80,7 +90,10 @@
|
|
|
80
90
|
"tsconfig-paths": "^4.2.0"
|
|
81
91
|
},
|
|
82
92
|
"devDependencies": {
|
|
83
|
-
"@tradejs/
|
|
93
|
+
"@tradejs/strategy-adaptive-momentum-ribbon": "^3.0.0",
|
|
94
|
+
"@tradejs/strategy-hyperliquid-consensus": "^3.0.0",
|
|
95
|
+
"@tradejs/strategy-trend-line": "^3.0.0",
|
|
96
|
+
"@tradejs/strategy-volume-divergence": "^3.0.0",
|
|
84
97
|
"@types/node": "^24",
|
|
85
98
|
"tsup": "^8.5.1",
|
|
86
99
|
"typescript": "^5.9"
|