@tradejs/node 2.0.6 → 2.0.7
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.js +47 -1
- package/dist/ai.mjs +1 -1
- package/dist/backtest.js +486 -84
- package/dist/backtest.mjs +30 -5
- package/dist/{chunk-2DZCHRP6.mjs → chunk-76TEMQKX.mjs} +418 -80
- package/dist/{chunk-IUZML4RK.mjs → chunk-PD25CABK.mjs} +47 -1
- package/dist/cli.js +47 -1
- package/dist/cli.mjs +1 -1
- package/dist/strategies.d.mts +49 -1
- package/dist/strategies.d.ts +49 -1
- package/dist/strategies.js +541 -90
- package/dist/strategies.mjs +78 -8
- package/package.json +4 -4
package/dist/strategies.mjs
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
+
BINANCE_BREADTH_UNIVERSE_KEYS,
|
|
3
|
+
buildBinanceBreadthUniverseSnapshot,
|
|
2
4
|
buildMlPayload,
|
|
3
5
|
enrichSignalWithBinanceMarketContext,
|
|
4
6
|
enrichSignalWithCoinMarketCapContext,
|
|
5
|
-
enrichSignalWithDerivativesContext
|
|
6
|
-
|
|
7
|
+
enrichSignalWithDerivativesContext,
|
|
8
|
+
getBinanceBreadthUniverseSnapshot,
|
|
9
|
+
getBinanceBreadthUniverses,
|
|
10
|
+
getPrimaryBinanceBreadthUniverse
|
|
11
|
+
} from "./chunk-76TEMQKX.mjs";
|
|
7
12
|
import {
|
|
8
13
|
require_lodash
|
|
9
14
|
} from "./chunk-GPR56UYQ.mjs";
|
|
@@ -24,7 +29,7 @@ import {
|
|
|
24
29
|
runAiPrompt,
|
|
25
30
|
runAiPromptLocal,
|
|
26
31
|
trimSeriesDeep
|
|
27
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-PD25CABK.mjs";
|
|
28
33
|
import {
|
|
29
34
|
createPineScriptLoader
|
|
30
35
|
} from "./chunk-IQKMII6L.mjs";
|
|
@@ -243,7 +248,7 @@ var getActiveRuntimeTrade = async (params) => {
|
|
|
243
248
|
redisKeys.runtimeTrade(userName, orderId),
|
|
244
249
|
null
|
|
245
250
|
);
|
|
246
|
-
if (!existing) {
|
|
251
|
+
if (!existing || existing.status !== "active") {
|
|
247
252
|
await delKey(
|
|
248
253
|
redisKeys.runtimeActiveTrade(userName, symbol, deploymentId ?? accountId)
|
|
249
254
|
);
|
|
@@ -463,7 +468,7 @@ var enrichSignalWithMlAi = async ({
|
|
|
463
468
|
return enrichSignalWithAi({ signal, userName, symbol, direction, env, ai });
|
|
464
469
|
};
|
|
465
470
|
var toFiniteNumberOrNull = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
466
|
-
var
|
|
471
|
+
var getOrderArrivalSnapshot = async ({
|
|
467
472
|
connector,
|
|
468
473
|
symbol
|
|
469
474
|
}) => {
|
|
@@ -508,6 +513,29 @@ var getArrivalSnapshot = async ({
|
|
|
508
513
|
};
|
|
509
514
|
}
|
|
510
515
|
};
|
|
516
|
+
var validateEntryProtectionAtArrival = ({
|
|
517
|
+
direction,
|
|
518
|
+
signalPrice,
|
|
519
|
+
bid,
|
|
520
|
+
ask,
|
|
521
|
+
arrivalMid,
|
|
522
|
+
takeProfits,
|
|
523
|
+
stopLossPrice
|
|
524
|
+
}) => {
|
|
525
|
+
const entryReference = direction === "LONG" ? ask ?? arrivalMid ?? signalPrice : bid ?? arrivalMid ?? signalPrice;
|
|
526
|
+
const stopReference = direction === "LONG" ? bid ?? arrivalMid ?? signalPrice : ask ?? arrivalMid ?? signalPrice;
|
|
527
|
+
if (!Number.isFinite(entryReference) || entryReference <= 0 || !Number.isFinite(stopReference) || stopReference <= 0) {
|
|
528
|
+
throw new Error("INVALID_ENTRY_REFERENCE_AT_ARRIVAL");
|
|
529
|
+
}
|
|
530
|
+
for (const takeProfit of takeProfits) {
|
|
531
|
+
if (!Number.isFinite(takeProfit.price) || takeProfit.price <= 0 || (direction === "LONG" ? takeProfit.price <= entryReference : takeProfit.price >= entryReference)) {
|
|
532
|
+
throw new Error("TAKE_PROFIT_CROSSED_BEFORE_ENTRY");
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
if (stopLossPrice != null && (!Number.isFinite(stopLossPrice) || stopLossPrice <= 0 || (direction === "LONG" ? stopLossPrice >= stopReference : stopLossPrice <= stopReference))) {
|
|
536
|
+
throw new Error("STOP_LOSS_CROSSED_BEFORE_ENTRY");
|
|
537
|
+
}
|
|
538
|
+
};
|
|
511
539
|
var resolveRuntimeTelemetryQuality = ({
|
|
512
540
|
signalClosePrice,
|
|
513
541
|
arrivalMid,
|
|
@@ -582,7 +610,22 @@ var executeEntryOrder = async ({
|
|
|
582
610
|
signal.orderQty = qty;
|
|
583
611
|
signal.orderValue = qty * currentPrice;
|
|
584
612
|
signal.orderFailureReason = void 0;
|
|
585
|
-
const arrivalSnapshot = await
|
|
613
|
+
const arrivalSnapshot = await getOrderArrivalSnapshot({ connector, symbol });
|
|
614
|
+
try {
|
|
615
|
+
validateEntryProtectionAtArrival({
|
|
616
|
+
direction,
|
|
617
|
+
signalPrice: currentPrice,
|
|
618
|
+
bid: arrivalSnapshot.bid,
|
|
619
|
+
ask: arrivalSnapshot.ask,
|
|
620
|
+
arrivalMid: arrivalSnapshot.arrivalMid,
|
|
621
|
+
takeProfits,
|
|
622
|
+
stopLossPrice
|
|
623
|
+
});
|
|
624
|
+
} catch (error) {
|
|
625
|
+
signal.orderStatus = "failed";
|
|
626
|
+
signal.orderFailureReason = error.message;
|
|
627
|
+
throw error;
|
|
628
|
+
}
|
|
586
629
|
const orderSubmitTime = Date.now();
|
|
587
630
|
const orderPlaced = await connector.placeOrder({
|
|
588
631
|
symbol,
|
|
@@ -771,6 +814,9 @@ var resolveStrategyConfig = async ({
|
|
|
771
814
|
};
|
|
772
815
|
|
|
773
816
|
// src/strategyRuntime.ts
|
|
817
|
+
import {
|
|
818
|
+
BACKTEST_WARNING_CODES
|
|
819
|
+
} from "@tradejs/types";
|
|
774
820
|
var buildExitOrderSignal = ({
|
|
775
821
|
strategyName,
|
|
776
822
|
symbol,
|
|
@@ -1479,6 +1525,19 @@ var executeEntryDecision = async ({
|
|
|
1479
1525
|
return signal;
|
|
1480
1526
|
}
|
|
1481
1527
|
await beforePlaceOrder();
|
|
1528
|
+
const arrivalSnapshot = await getOrderArrivalSnapshot({
|
|
1529
|
+
connector,
|
|
1530
|
+
symbol
|
|
1531
|
+
});
|
|
1532
|
+
validateEntryProtectionAtArrival({
|
|
1533
|
+
direction: decision.entryContext.direction,
|
|
1534
|
+
signalPrice: decision.entryContext.prices.currentPrice,
|
|
1535
|
+
bid: arrivalSnapshot.bid,
|
|
1536
|
+
ask: arrivalSnapshot.ask,
|
|
1537
|
+
arrivalMid: arrivalSnapshot.arrivalMid,
|
|
1538
|
+
takeProfits: decision.orderPlan.takeProfits,
|
|
1539
|
+
stopLossPrice: decision.orderPlan.stopLossPrice
|
|
1540
|
+
});
|
|
1482
1541
|
const orderPlaced = await connector.placeOrder({
|
|
1483
1542
|
symbol,
|
|
1484
1543
|
qty: decision.orderPlan.qty,
|
|
@@ -1540,7 +1599,11 @@ var executeEntryDecision = async ({
|
|
|
1540
1599
|
entry,
|
|
1541
1600
|
market
|
|
1542
1601
|
});
|
|
1543
|
-
|
|
1602
|
+
if (err?.message === BACKTEST_WARNING_CODES.TAKE_PROFIT_CROSSED_BEFORE_ENTRY) {
|
|
1603
|
+
logger3.warn("order warning: %s %s", symbol, err);
|
|
1604
|
+
} else {
|
|
1605
|
+
logger3.error("order error: %s %s", symbol, err);
|
|
1606
|
+
}
|
|
1544
1607
|
return signal ?? "ORDER_ERROR";
|
|
1545
1608
|
}
|
|
1546
1609
|
return signal ?? decision.code;
|
|
@@ -2804,6 +2867,7 @@ var createCloseAllOnGlobalProfitBeforeSignalsHook = ({
|
|
|
2804
2867
|
};
|
|
2805
2868
|
};
|
|
2806
2869
|
export {
|
|
2870
|
+
BINANCE_BREADTH_UNIVERSE_KEYS,
|
|
2807
2871
|
DEFAULT_AI_MODEL,
|
|
2808
2872
|
MAX_AI_SERIES_POINTS,
|
|
2809
2873
|
askAI,
|
|
@@ -2811,6 +2875,7 @@ export {
|
|
|
2811
2875
|
buildAiPayload,
|
|
2812
2876
|
buildAiPrompts,
|
|
2813
2877
|
buildAiSystemPrompt,
|
|
2878
|
+
buildBinanceBreadthUniverseSnapshot,
|
|
2814
2879
|
buildCompactAiIndicatorsSnapshot,
|
|
2815
2880
|
closeOppositePositionsBeforeOpen,
|
|
2816
2881
|
createCloseAllOnGlobalProfitBeforeSignalsHook,
|
|
@@ -2828,8 +2893,12 @@ export {
|
|
|
2828
2893
|
ensureStrategyPluginsLoaded,
|
|
2829
2894
|
executeEntryOrder,
|
|
2830
2895
|
getAvailableStrategyNames,
|
|
2896
|
+
getBinanceBreadthUniverseSnapshot,
|
|
2897
|
+
getBinanceBreadthUniverses,
|
|
2831
2898
|
getDeterministicAiGateContext,
|
|
2832
2899
|
getOpenRouterModelKwargs,
|
|
2900
|
+
getOrderArrivalSnapshot,
|
|
2901
|
+
getPrimaryBinanceBreadthUniverse,
|
|
2833
2902
|
getRegisteredManifests,
|
|
2834
2903
|
getRegisteredStrategies,
|
|
2835
2904
|
getStrategyCreator,
|
|
@@ -2842,5 +2911,6 @@ export {
|
|
|
2842
2911
|
runAiPrompt,
|
|
2843
2912
|
runAiPromptLocal,
|
|
2844
2913
|
strategies,
|
|
2845
|
-
trimSeriesDeep
|
|
2914
|
+
trimSeriesDeep,
|
|
2915
|
+
validateEntryProtectionAtArrival
|
|
2846
2916
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tradejs/node",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.7",
|
|
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",
|
|
@@ -67,9 +67,9 @@
|
|
|
67
67
|
"dependencies": {
|
|
68
68
|
"@langchain/core": "^1.2.3",
|
|
69
69
|
"@langchain/openai": "^1.5.5",
|
|
70
|
-
"@tradejs/core": "^2.0.
|
|
71
|
-
"@tradejs/infra": "^2.0.
|
|
72
|
-
"@tradejs/types": "^2.0.
|
|
70
|
+
"@tradejs/core": "^2.0.7",
|
|
71
|
+
"@tradejs/infra": "^2.0.7",
|
|
72
|
+
"@tradejs/types": "^2.0.7",
|
|
73
73
|
"chalk": "4.1.2",
|
|
74
74
|
"ioredis": "5.11.1",
|
|
75
75
|
"pinets": "0.8.12",
|