@tradejs/node 3.1.27 → 3.1.28-beta.252
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 +1 -0
- package/dist/ai.mjs +1 -1
- package/dist/backtest.d.mts +3 -1
- package/dist/backtest.d.ts +3 -1
- package/dist/backtest.js +287 -39
- package/dist/backtest.mjs +30 -16
- package/dist/{chunk-NQO2MFP6.mjs → chunk-K2YQ3MQC.mjs} +58 -10
- package/dist/{chunk-FB5NUEOQ.mjs → chunk-OFVUEYUR.mjs} +4 -1
- package/dist/{chunk-IKRSNRP6.mjs → chunk-UITD6LG6.mjs} +83 -4
- package/dist/{chunk-XHNJ757K.mjs → chunk-VQSGH7YA.mjs} +341 -22
- package/dist/cli.js +2 -1
- package/dist/cli.mjs +1 -1
- package/dist/{registry-DHTLjQcr.d.mts → registry-3TsO1Ff1.d.mts} +2 -2
- package/dist/{registry-DHTLjQcr.d.ts → registry-3TsO1Ff1.d.ts} +2 -2
- package/dist/registry.d.mts +1 -1
- package/dist/registry.d.ts +1 -1
- package/dist/registry.js +260 -23
- package/dist/registry.mjs +2 -2
- package/dist/runtimeDashboard.js +378 -37
- package/dist/runtimeDashboard.mjs +54 -8
- package/dist/runtimeStrategies.d.mts +4 -1
- package/dist/runtimeStrategies.d.ts +4 -1
- package/dist/runtimeStrategies.js +327 -34
- package/dist/runtimeStrategies.mjs +3 -3
- package/dist/runtimeTrades.d.mts +2 -1
- package/dist/runtimeTrades.d.ts +2 -1
- package/dist/runtimeTrades.js +4 -1
- package/dist/runtimeTrades.mjs +1 -1
- package/dist/strategies.d.mts +14 -2
- package/dist/strategies.d.ts +14 -2
- package/dist/strategies.js +417 -24
- package/dist/strategies.mjs +4 -2
- package/package.json +5 -5
|
@@ -934,6 +934,7 @@ var createStrategyRegistryState = () => ({
|
|
|
934
934
|
strategyManifestsMap: /* @__PURE__ */ new Map(),
|
|
935
935
|
strategyEntriesMap: /* @__PURE__ */ new Map(),
|
|
936
936
|
strategySourcesMap: /* @__PURE__ */ new Map(),
|
|
937
|
+
strategyModuleResolutions: /* @__PURE__ */ new Map(),
|
|
937
938
|
pluginsLoadPromise: null
|
|
938
939
|
});
|
|
939
940
|
var registryStateByProjectRoot = sharedStrategyRegistry.registryStateByProjectRoot;
|
|
@@ -995,7 +996,7 @@ var validateStrategyEntries = (moduleName, entries, state) => {
|
|
|
995
996
|
const strategyName = entry?.manifest?.name;
|
|
996
997
|
if (typeof strategyName !== "string" || !strategyName.trim()) {
|
|
997
998
|
issues.push(`${entryPath}: manifest.name is required`);
|
|
998
|
-
} else if (names.has(strategyName) || state
|
|
999
|
+
} else if (names.has(strategyName) || state?.strategyEntriesMap.has(strategyName)) {
|
|
999
1000
|
issues.push(`${entryPath}: duplicate strategy ${strategyName}`);
|
|
1000
1001
|
} else {
|
|
1001
1002
|
names.add(strategyName);
|
|
@@ -1057,6 +1058,72 @@ var importStrategyPluginModule = async (moduleName, cwd = getTradejsProjectCwd()
|
|
|
1057
1058
|
moduleName
|
|
1058
1059
|
);
|
|
1059
1060
|
};
|
|
1061
|
+
var resolveStrategyModuleEntry = async ({
|
|
1062
|
+
strategyName,
|
|
1063
|
+
moduleName,
|
|
1064
|
+
cwd
|
|
1065
|
+
}) => {
|
|
1066
|
+
const { projectRoot, state } = getStrategyRegistryState(cwd);
|
|
1067
|
+
const source = moduleName.trim();
|
|
1068
|
+
const resolvedModuleName = resolvePluginModuleSpecifier(source, projectRoot);
|
|
1069
|
+
const cacheKey = `${resolvedModuleName}\0${strategyName}`;
|
|
1070
|
+
const cached = state.strategyModuleResolutions.get(cacheKey);
|
|
1071
|
+
if (cached) return cached;
|
|
1072
|
+
const resolution = (async () => {
|
|
1073
|
+
const moduleExport = await importStrategyPluginModule(
|
|
1074
|
+
resolvedModuleName,
|
|
1075
|
+
projectRoot
|
|
1076
|
+
);
|
|
1077
|
+
const pluginDefinition = extractStrategyPluginDefinition(moduleExport);
|
|
1078
|
+
if (!pluginDefinition) {
|
|
1079
|
+
throw new Error(`${source}: export { strategyEntries } is missing`);
|
|
1080
|
+
}
|
|
1081
|
+
const issues = validateStrategyEntries(
|
|
1082
|
+
source,
|
|
1083
|
+
pluginDefinition.strategyEntries
|
|
1084
|
+
);
|
|
1085
|
+
if (issues.length > 0) {
|
|
1086
|
+
throw new Error(
|
|
1087
|
+
["Invalid TradeJS strategy module:", ...issues].join("\n")
|
|
1088
|
+
);
|
|
1089
|
+
}
|
|
1090
|
+
const entry = pluginDefinition.strategyEntries.find(
|
|
1091
|
+
(candidate) => candidate.manifest.name === strategyName
|
|
1092
|
+
);
|
|
1093
|
+
if (!entry) {
|
|
1094
|
+
throw new Error(`${source}: strategy ${strategyName} is missing`);
|
|
1095
|
+
}
|
|
1096
|
+
const factory = sharedStrategyRegistry.strategyRuntimeFactory;
|
|
1097
|
+
if (!factory) {
|
|
1098
|
+
throw new Error("Strategy runtime factory is not configured");
|
|
1099
|
+
}
|
|
1100
|
+
const manifestsByName = new Map(
|
|
1101
|
+
pluginDefinition.strategyEntries.map(
|
|
1102
|
+
(candidate) => [candidate.manifest.name, candidate.manifest]
|
|
1103
|
+
)
|
|
1104
|
+
);
|
|
1105
|
+
return {
|
|
1106
|
+
entry,
|
|
1107
|
+
creator: factory({
|
|
1108
|
+
strategyName,
|
|
1109
|
+
defaults: entry.defaults,
|
|
1110
|
+
createCore: entry.createCore,
|
|
1111
|
+
manifest: entry.manifest,
|
|
1112
|
+
detectorKey: entry.detectorKey,
|
|
1113
|
+
detectorNoSignalSkipReason: entry.detectorNoSignalSkipReason,
|
|
1114
|
+
resolveRegisteredManifest: (name) => manifestsByName.get(name) ?? state.strategyManifestsMap.get(name)
|
|
1115
|
+
}),
|
|
1116
|
+
source
|
|
1117
|
+
};
|
|
1118
|
+
})();
|
|
1119
|
+
state.strategyModuleResolutions.set(cacheKey, resolution);
|
|
1120
|
+
try {
|
|
1121
|
+
return await resolution;
|
|
1122
|
+
} catch (error) {
|
|
1123
|
+
state.strategyModuleResolutions.delete(cacheKey);
|
|
1124
|
+
throw error;
|
|
1125
|
+
}
|
|
1126
|
+
};
|
|
1060
1127
|
var ensureStrategyPluginsLoaded = async (cwd = getTradejsProjectCwd()) => {
|
|
1061
1128
|
const { projectRoot, state } = getStrategyRegistryState(cwd);
|
|
1062
1129
|
if (!state.pluginsLoadPromise) {
|
|
@@ -1134,17 +1201,29 @@ var ensureStrategyPluginsLoaded = async (cwd = getTradejsProjectCwd()) => {
|
|
|
1134
1201
|
}
|
|
1135
1202
|
await state.pluginsLoadPromise;
|
|
1136
1203
|
};
|
|
1137
|
-
var getStrategyCreator = async (name, cwd = getTradejsProjectCwd()) => {
|
|
1204
|
+
var getStrategyCreator = async (name, cwd = getTradejsProjectCwd(), moduleName) => {
|
|
1205
|
+
if (moduleName?.trim()) {
|
|
1206
|
+
await ensureStrategyPluginsLoaded(cwd);
|
|
1207
|
+
return (await resolveStrategyModuleEntry({ strategyName: name, moduleName, cwd })).creator;
|
|
1208
|
+
}
|
|
1138
1209
|
await ensureStrategyPluginsLoaded(cwd);
|
|
1139
1210
|
const { state } = getStrategyRegistryState(cwd);
|
|
1140
1211
|
return state.strategyCreators.get(name);
|
|
1141
1212
|
};
|
|
1142
|
-
var getStrategyEntry = async (name, cwd = getTradejsProjectCwd()) => {
|
|
1213
|
+
var getStrategyEntry = async (name, cwd = getTradejsProjectCwd(), moduleName) => {
|
|
1214
|
+
if (moduleName?.trim()) {
|
|
1215
|
+
await ensureStrategyPluginsLoaded(cwd);
|
|
1216
|
+
return (await resolveStrategyModuleEntry({ strategyName: name, moduleName, cwd })).entry;
|
|
1217
|
+
}
|
|
1143
1218
|
await ensureStrategyPluginsLoaded(cwd);
|
|
1144
1219
|
const { state } = getStrategyRegistryState(cwd);
|
|
1145
1220
|
return state.strategyEntriesMap.get(name);
|
|
1146
1221
|
};
|
|
1147
|
-
var getStrategyPluginSource = async (name, cwd = getTradejsProjectCwd()) => {
|
|
1222
|
+
var getStrategyPluginSource = async (name, cwd = getTradejsProjectCwd(), moduleName) => {
|
|
1223
|
+
if (moduleName?.trim()) {
|
|
1224
|
+
await ensureStrategyPluginsLoaded(cwd);
|
|
1225
|
+
return (await resolveStrategyModuleEntry({ strategyName: name, moduleName, cwd })).source;
|
|
1226
|
+
}
|
|
1148
1227
|
await ensureStrategyPluginsLoaded(cwd);
|
|
1149
1228
|
const { state } = getStrategyRegistryState(cwd);
|
|
1150
1229
|
return state.strategySourcesMap.get(name);
|
|
@@ -2363,9 +2442,40 @@ var DEFAULT_MAX_AGE_BY_INTERVAL = {
|
|
|
2363
2442
|
"15m": 30 * 6e4,
|
|
2364
2443
|
"1h": 2 * 60 * 6e4
|
|
2365
2444
|
};
|
|
2445
|
+
var MARKET_CONTEXT_PRELOAD_CHUNK_MS = 7 * 24 * 60 * 6e4;
|
|
2366
2446
|
var binanceMarketContextUnavailable = false;
|
|
2367
2447
|
var referenceRowsCache = /* @__PURE__ */ new Map();
|
|
2368
2448
|
var breadthCache = /* @__PURE__ */ new Map();
|
|
2449
|
+
var BREADTH_COMMON_NUMERIC_FIELDS = [
|
|
2450
|
+
"symbolsCount",
|
|
2451
|
+
"advancers",
|
|
2452
|
+
"decliners",
|
|
2453
|
+
"unchanged",
|
|
2454
|
+
"advanceDeclineRatio",
|
|
2455
|
+
"pctAboveMa20",
|
|
2456
|
+
"pctAboveMa50",
|
|
2457
|
+
"equalWeightedReturn",
|
|
2458
|
+
"volumeWeightedReturn",
|
|
2459
|
+
"dispersion"
|
|
2460
|
+
];
|
|
2461
|
+
var BREADTH_REGIME_NUMERIC_FIELDS = [
|
|
2462
|
+
"btcReturn1h",
|
|
2463
|
+
"btcReturn4h",
|
|
2464
|
+
"btcReturn24h",
|
|
2465
|
+
"altBasketReturn1h",
|
|
2466
|
+
"altBasketReturn4h",
|
|
2467
|
+
"altBasketReturn24h",
|
|
2468
|
+
"btcVsAltReturn1h",
|
|
2469
|
+
"btcVsAltReturn4h",
|
|
2470
|
+
"btcVsAltReturn24h",
|
|
2471
|
+
"btcTurnoverShare1h",
|
|
2472
|
+
"btcTurnoverShare24h",
|
|
2473
|
+
"btcTurnoverShareChange24h",
|
|
2474
|
+
"altVolToBtcVol24h",
|
|
2475
|
+
"altDispersion24h"
|
|
2476
|
+
];
|
|
2477
|
+
var preloadedTradeFlowBySymbol = null;
|
|
2478
|
+
var preloadedBreadthByUniverse = null;
|
|
2369
2479
|
var parseEnabledFlag = (value, env) => {
|
|
2370
2480
|
const normalized = String(value ?? "").trim().toLowerCase();
|
|
2371
2481
|
if (!normalized)
|
|
@@ -2401,6 +2511,100 @@ var hasBaseContext = (signal) => Boolean(
|
|
|
2401
2511
|
signal.additionalIndicators?.baseContext && typeof signal.additionalIndicators.baseContext === "object" && !Array.isArray(signal.additionalIndicators.baseContext)
|
|
2402
2512
|
);
|
|
2403
2513
|
var isBinanceMarketContextEnabled = (env) => parseEnabledFlag(process.env.BINANCE_MARKET_CONTEXT_ENABLED, env);
|
|
2514
|
+
var latestIndexAtOrBefore = (timestamps, timestamp) => {
|
|
2515
|
+
if (!timestamps?.length) return -1;
|
|
2516
|
+
let low = 0;
|
|
2517
|
+
let high = timestamps.length - 1;
|
|
2518
|
+
let match = -1;
|
|
2519
|
+
while (low <= high) {
|
|
2520
|
+
const middle = Math.floor((low + high) / 2);
|
|
2521
|
+
const rowTimestamp = timestamps[middle];
|
|
2522
|
+
if (rowTimestamp == null) break;
|
|
2523
|
+
if (rowTimestamp <= timestamp) {
|
|
2524
|
+
match = middle;
|
|
2525
|
+
low = middle + 1;
|
|
2526
|
+
} else {
|
|
2527
|
+
high = middle - 1;
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
return match;
|
|
2531
|
+
};
|
|
2532
|
+
var latestChunkAtOrBefore = (chunks, timestamp) => {
|
|
2533
|
+
if (!chunks?.length) return null;
|
|
2534
|
+
let low = 0;
|
|
2535
|
+
let high = chunks.length - 1;
|
|
2536
|
+
let match = null;
|
|
2537
|
+
while (low <= high) {
|
|
2538
|
+
const middle = Math.floor((low + high) / 2);
|
|
2539
|
+
const chunk = chunks[middle];
|
|
2540
|
+
const firstTimestamp = chunk?.timestamps[0];
|
|
2541
|
+
if (!chunk || firstTimestamp == null) break;
|
|
2542
|
+
if (firstTimestamp <= timestamp) {
|
|
2543
|
+
match = chunk;
|
|
2544
|
+
low = middle + 1;
|
|
2545
|
+
} else {
|
|
2546
|
+
high = middle - 1;
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
return match;
|
|
2550
|
+
};
|
|
2551
|
+
var unpackedNumber = (value) => value == null || Number.isNaN(value) ? null : value;
|
|
2552
|
+
var unpackTradeFlowRow = (chunks, timestamp) => {
|
|
2553
|
+
const rows = latestChunkAtOrBefore(chunks, timestamp);
|
|
2554
|
+
const index = latestIndexAtOrBefore(rows?.timestamps, timestamp);
|
|
2555
|
+
if (!rows || index < 0) return null;
|
|
2556
|
+
return {
|
|
2557
|
+
symbol: rows.symbol,
|
|
2558
|
+
interval: rows.interval,
|
|
2559
|
+
ts: new Date(rows.timestamps[index]),
|
|
2560
|
+
trades: unpackedNumber(rows.columns.trades[index]) ?? 0,
|
|
2561
|
+
buyBaseVolume: unpackedNumber(rows.columns.buyBaseVolume[index]),
|
|
2562
|
+
sellBaseVolume: unpackedNumber(rows.columns.sellBaseVolume[index]),
|
|
2563
|
+
buyQuoteVolume: unpackedNumber(rows.columns.buyQuoteVolume[index]),
|
|
2564
|
+
sellQuoteVolume: unpackedNumber(rows.columns.sellQuoteVolume[index]),
|
|
2565
|
+
netBaseDelta: unpackedNumber(rows.columns.netBaseDelta[index]),
|
|
2566
|
+
netQuoteDelta: unpackedNumber(rows.columns.netQuoteDelta[index]),
|
|
2567
|
+
buyPressurePct: unpackedNumber(rows.columns.buyPressurePct[index])
|
|
2568
|
+
};
|
|
2569
|
+
};
|
|
2570
|
+
var unpackBreadthRow = (chunks, timestamp) => {
|
|
2571
|
+
const rows = latestChunkAtOrBefore(chunks, timestamp);
|
|
2572
|
+
const index = latestIndexAtOrBefore(rows?.timestamps, timestamp);
|
|
2573
|
+
if (!rows || index < 0) return null;
|
|
2574
|
+
const commonNumeric = Object.fromEntries(
|
|
2575
|
+
BREADTH_COMMON_NUMERIC_FIELDS.map((field) => [
|
|
2576
|
+
field,
|
|
2577
|
+
unpackedNumber(rows.commonColumns[field][index])
|
|
2578
|
+
])
|
|
2579
|
+
);
|
|
2580
|
+
const regimeNumeric = Object.fromEntries(
|
|
2581
|
+
BREADTH_REGIME_NUMERIC_FIELDS.map((field) => [
|
|
2582
|
+
field,
|
|
2583
|
+
unpackedNumber(rows.regimeColumns?.[field][index])
|
|
2584
|
+
])
|
|
2585
|
+
);
|
|
2586
|
+
return {
|
|
2587
|
+
universe: rows.universe,
|
|
2588
|
+
interval: rows.interval,
|
|
2589
|
+
ts: new Date(rows.timestamps[index]),
|
|
2590
|
+
...commonNumeric,
|
|
2591
|
+
...regimeNumeric,
|
|
2592
|
+
symbolsCount: commonNumeric.symbolsCount ?? 0,
|
|
2593
|
+
advancers: commonNumeric.advancers ?? 0,
|
|
2594
|
+
decliners: commonNumeric.decliners ?? 0,
|
|
2595
|
+
unchanged: commonNumeric.unchanged ?? 0,
|
|
2596
|
+
btcAltRegime: rows.regimes?.[index] ?? null
|
|
2597
|
+
};
|
|
2598
|
+
};
|
|
2599
|
+
var toAsOfRow = (row, timestamp, maxAgeMs) => {
|
|
2600
|
+
if (!row) return null;
|
|
2601
|
+
const ageMs = timestamp - row.ts.getTime();
|
|
2602
|
+
return {
|
|
2603
|
+
...row,
|
|
2604
|
+
ageMs: Number.isFinite(ageMs) ? ageMs : null,
|
|
2605
|
+
stale: !Number.isFinite(ageMs) || ageMs < 0 || ageMs > maxAgeMs
|
|
2606
|
+
};
|
|
2607
|
+
};
|
|
2404
2608
|
var toTradeFlowContext = (row, interval) => row ? {
|
|
2405
2609
|
source: "binance_agg_trades",
|
|
2406
2610
|
interval,
|
|
@@ -2423,6 +2627,24 @@ var getCachedReferenceRows = ({
|
|
|
2423
2627
|
maxAgeMs,
|
|
2424
2628
|
abortSignal
|
|
2425
2629
|
}) => {
|
|
2630
|
+
if (preloadedTradeFlowBySymbol) {
|
|
2631
|
+
return Promise.resolve(
|
|
2632
|
+
referenceSymbols.map((symbol) => ({
|
|
2633
|
+
symbol,
|
|
2634
|
+
tradeFlow: toTradeFlowContext(
|
|
2635
|
+
toAsOfRow(
|
|
2636
|
+
unpackTradeFlowRow(
|
|
2637
|
+
preloadedTradeFlowBySymbol?.get(symbol),
|
|
2638
|
+
timestamp
|
|
2639
|
+
),
|
|
2640
|
+
timestamp,
|
|
2641
|
+
maxAgeMs
|
|
2642
|
+
),
|
|
2643
|
+
interval
|
|
2644
|
+
)
|
|
2645
|
+
}))
|
|
2646
|
+
);
|
|
2647
|
+
}
|
|
2426
2648
|
const key = `${referenceSymbols.join(",")}:${interval}:${timestamp}:${maxAgeMs}`;
|
|
2427
2649
|
const cached = referenceRowsCache.get(key);
|
|
2428
2650
|
if (cached) return cached;
|
|
@@ -2452,6 +2674,18 @@ var getCachedBreadth = ({
|
|
|
2452
2674
|
maxAgeMs,
|
|
2453
2675
|
abortSignal
|
|
2454
2676
|
}) => {
|
|
2677
|
+
if (preloadedBreadthByUniverse) {
|
|
2678
|
+
return Promise.resolve(
|
|
2679
|
+
toAsOfRow(
|
|
2680
|
+
unpackBreadthRow(
|
|
2681
|
+
preloadedBreadthByUniverse.get(breadthUniverse),
|
|
2682
|
+
timestamp
|
|
2683
|
+
),
|
|
2684
|
+
timestamp,
|
|
2685
|
+
maxAgeMs
|
|
2686
|
+
)
|
|
2687
|
+
);
|
|
2688
|
+
}
|
|
2455
2689
|
const key = `${breadthUniverse}:${interval}:${timestamp}:${maxAgeMs}`;
|
|
2456
2690
|
const cached = breadthCache.get(key);
|
|
2457
2691
|
if (cached) return cached;
|
|
@@ -2658,12 +2892,20 @@ var SOURCE_EXCHANGE_LIQUIDITY = "coinmarketcap_exchange_liquidity";
|
|
|
2658
2892
|
var SOURCE_FEAR_GREED = "coinmarketcap_fear_greed";
|
|
2659
2893
|
var SOURCE_INDEX = "coinmarketcap_index";
|
|
2660
2894
|
var DAY_MS = 864e5;
|
|
2895
|
+
var MAX_TIMESTAMP_CACHE_ENTRIES = 512;
|
|
2661
2896
|
var coinMarketCapContextUnavailable = false;
|
|
2662
2897
|
var globalContextCache = /* @__PURE__ */ new Map();
|
|
2663
2898
|
var referenceContextCache = /* @__PURE__ */ new Map();
|
|
2664
2899
|
var exchangeLiquidityContextCache = /* @__PURE__ */ new Map();
|
|
2665
2900
|
var fearGreedContextCache = /* @__PURE__ */ new Map();
|
|
2666
2901
|
var indexContextCache = /* @__PURE__ */ new Map();
|
|
2902
|
+
var setBoundedCache = (cache, key, value) => {
|
|
2903
|
+
if (cache.size >= MAX_TIMESTAMP_CACHE_ENTRIES) {
|
|
2904
|
+
const oldestKey = cache.keys().next().value;
|
|
2905
|
+
if (oldestKey != null) cache.delete(oldestKey);
|
|
2906
|
+
}
|
|
2907
|
+
cache.set(key, value);
|
|
2908
|
+
};
|
|
2667
2909
|
var parseEnabledFlag2 = (value, env) => {
|
|
2668
2910
|
const normalized = String(value ?? "").trim().toLowerCase();
|
|
2669
2911
|
if (!normalized) {
|
|
@@ -2770,7 +3012,7 @@ var getCachedGlobalContext = ({
|
|
|
2770
3012
|
maxAgeMs,
|
|
2771
3013
|
...abortSignal ? { signal: abortSignal } : {}
|
|
2772
3014
|
});
|
|
2773
|
-
globalContextCache
|
|
3015
|
+
setBoundedCache(globalContextCache, key, promise);
|
|
2774
3016
|
void promise.catch(() => globalContextCache.delete(key));
|
|
2775
3017
|
return promise;
|
|
2776
3018
|
};
|
|
@@ -2790,7 +3032,7 @@ var getCachedReferenceContexts = ({
|
|
|
2790
3032
|
maxAgeMs,
|
|
2791
3033
|
...abortSignal ? { signal: abortSignal } : {}
|
|
2792
3034
|
});
|
|
2793
|
-
referenceContextCache
|
|
3035
|
+
setBoundedCache(referenceContextCache, key, promise);
|
|
2794
3036
|
void promise.catch(() => referenceContextCache.delete(key));
|
|
2795
3037
|
return promise;
|
|
2796
3038
|
};
|
|
@@ -2809,7 +3051,7 @@ var getCachedExchangeLiquidityContext = ({
|
|
|
2809
3051
|
maxAgeMs,
|
|
2810
3052
|
...abortSignal ? { signal: abortSignal } : {}
|
|
2811
3053
|
});
|
|
2812
|
-
exchangeLiquidityContextCache
|
|
3054
|
+
setBoundedCache(exchangeLiquidityContextCache, key, promise);
|
|
2813
3055
|
void promise.catch(() => exchangeLiquidityContextCache.delete(key));
|
|
2814
3056
|
return promise;
|
|
2815
3057
|
};
|
|
@@ -2828,7 +3070,7 @@ var getCachedFearGreedContext = ({
|
|
|
2828
3070
|
maxAgeMs,
|
|
2829
3071
|
...abortSignal ? { signal: abortSignal } : {}
|
|
2830
3072
|
});
|
|
2831
|
-
fearGreedContextCache
|
|
3073
|
+
setBoundedCache(fearGreedContextCache, key, promise);
|
|
2832
3074
|
void promise.catch(() => fearGreedContextCache.delete(key));
|
|
2833
3075
|
return promise;
|
|
2834
3076
|
};
|
|
@@ -2848,7 +3090,7 @@ var getCachedIndexContexts = ({
|
|
|
2848
3090
|
maxAgeMs,
|
|
2849
3091
|
...abortSignal ? { signal: abortSignal } : {}
|
|
2850
3092
|
});
|
|
2851
|
-
indexContextCache
|
|
3093
|
+
setBoundedCache(indexContextCache, key, promise);
|
|
2852
3094
|
void promise.catch(() => indexContextCache.delete(key));
|
|
2853
3095
|
return promise;
|
|
2854
3096
|
};
|
|
@@ -3658,7 +3900,7 @@ var signalIntervalToMarketInterval2 = (value) => {
|
|
|
3658
3900
|
var hasBaseContext3 = (signal) => Boolean(
|
|
3659
3901
|
signal.additionalIndicators?.baseContext && typeof signal.additionalIndicators.baseContext === "object" && !Array.isArray(signal.additionalIndicators.baseContext)
|
|
3660
3902
|
);
|
|
3661
|
-
var
|
|
3903
|
+
var setBoundedCache2 = (key, value) => {
|
|
3662
3904
|
if (contextCache.size >= MAX_CACHE_ENTRIES) {
|
|
3663
3905
|
const oldestKey = contextCache.keys().next().value;
|
|
3664
3906
|
if (oldestKey != null) contextCache.delete(oldestKey);
|
|
@@ -3905,7 +4147,7 @@ var loadHyperliquidWhaleFlowContext = async (params) => {
|
|
|
3905
4147
|
whaleRegistryFingerprint: whales.fingerprint,
|
|
3906
4148
|
...params.abortSignal ? { signal: params.abortSignal } : {}
|
|
3907
4149
|
});
|
|
3908
|
-
|
|
4150
|
+
setBoundedCache2(cacheKey, pending);
|
|
3909
4151
|
}
|
|
3910
4152
|
row = await pending;
|
|
3911
4153
|
}
|
|
@@ -5040,20 +5282,23 @@ var buildHookCtx = ({
|
|
|
5040
5282
|
strategyConfig,
|
|
5041
5283
|
env,
|
|
5042
5284
|
isConfigFromBacktest
|
|
5043
|
-
}) =>
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5285
|
+
}) => {
|
|
5286
|
+
const context = {
|
|
5287
|
+
connector,
|
|
5288
|
+
strategyName,
|
|
5289
|
+
userName,
|
|
5290
|
+
symbol
|
|
5291
|
+
};
|
|
5292
|
+
if (universe) context.universe = universe;
|
|
5293
|
+
if (assetClass) context.assetClass = assetClass;
|
|
5294
|
+
if (accountId) context.accountId = accountId;
|
|
5295
|
+
if (deploymentId) context.deploymentId = deploymentId;
|
|
5296
|
+
if (policyProfileId) context.policyProfileId = policyProfileId;
|
|
5297
|
+
context.strategyConfig = strategyConfig;
|
|
5298
|
+
context.env = env;
|
|
5299
|
+
context.isConfigFromBacktest = isConfigFromBacktest;
|
|
5300
|
+
return context;
|
|
5301
|
+
};
|
|
5057
5302
|
var shouldRecordRuntimeJournal = ({
|
|
5058
5303
|
env,
|
|
5059
5304
|
config
|
|
@@ -6398,7 +6643,13 @@ var DEPLOYMENT_KEYS = /* @__PURE__ */ new Set([
|
|
|
6398
6643
|
"assetClasses",
|
|
6399
6644
|
"tickers"
|
|
6400
6645
|
]);
|
|
6401
|
-
var STRATEGY_KEYS = /* @__PURE__ */ new Set([
|
|
6646
|
+
var STRATEGY_KEYS = /* @__PURE__ */ new Set([
|
|
6647
|
+
"module",
|
|
6648
|
+
"generation",
|
|
6649
|
+
"enabled",
|
|
6650
|
+
"selection",
|
|
6651
|
+
"config"
|
|
6652
|
+
]);
|
|
6402
6653
|
var SELECTION_KEYS = /* @__PURE__ */ new Set(["tickers"]);
|
|
6403
6654
|
var FORBIDDEN_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
6404
6655
|
"ACCOUNT_ID",
|
|
@@ -6470,6 +6721,39 @@ var readRuntimePackageManifest = async (projectRoot) => {
|
|
|
6470
6721
|
}
|
|
6471
6722
|
return value;
|
|
6472
6723
|
};
|
|
6724
|
+
var parseNpmAliasReference = (value) => {
|
|
6725
|
+
if (typeof value !== "string" || !value.startsWith("npm:")) return null;
|
|
6726
|
+
const target = value.slice("npm:".length);
|
|
6727
|
+
const versionSeparator = target.lastIndexOf("@");
|
|
6728
|
+
if (versionSeparator <= 0 || versionSeparator === target.length - 1) {
|
|
6729
|
+
return null;
|
|
6730
|
+
}
|
|
6731
|
+
return {
|
|
6732
|
+
packageName: target.slice(0, versionSeparator),
|
|
6733
|
+
version: target.slice(versionSeparator + 1)
|
|
6734
|
+
};
|
|
6735
|
+
};
|
|
6736
|
+
var verifyInstalledPackageName = async ({
|
|
6737
|
+
projectRoot,
|
|
6738
|
+
packageName,
|
|
6739
|
+
installedName,
|
|
6740
|
+
installedVersion,
|
|
6741
|
+
projectPackage
|
|
6742
|
+
}) => {
|
|
6743
|
+
if (installedName === void 0 || installedName === packageName) return;
|
|
6744
|
+
if (projectPackage || typeof installedName !== "string") {
|
|
6745
|
+
throw new Error("name is invalid");
|
|
6746
|
+
}
|
|
6747
|
+
const projectManifest = JSON.parse(
|
|
6748
|
+
await (0, import_promises.readFile)(import_node_path.default.join(projectRoot, "package.json"), "utf8")
|
|
6749
|
+
);
|
|
6750
|
+
const alias = parseNpmAliasReference(
|
|
6751
|
+
projectManifest.dependencies?.[packageName]
|
|
6752
|
+
);
|
|
6753
|
+
if (alias?.packageName !== installedName || alias.version !== installedVersion) {
|
|
6754
|
+
throw new Error("name or alias target is invalid");
|
|
6755
|
+
}
|
|
6756
|
+
};
|
|
6473
6757
|
var readInstalledPackageMetadata = async ({
|
|
6474
6758
|
projectRoot,
|
|
6475
6759
|
packageName,
|
|
@@ -6483,9 +6767,16 @@ var readInstalledPackageMetadata = async ({
|
|
|
6483
6767
|
);
|
|
6484
6768
|
try {
|
|
6485
6769
|
const packageJson = JSON.parse(await (0, import_promises.readFile)(packageJsonPath, "utf8"));
|
|
6486
|
-
if (
|
|
6487
|
-
throw new Error("
|
|
6770
|
+
if (typeof packageJson.version !== "string" || !packageJson.version.trim()) {
|
|
6771
|
+
throw new Error("version is invalid");
|
|
6488
6772
|
}
|
|
6773
|
+
await verifyInstalledPackageName({
|
|
6774
|
+
projectRoot,
|
|
6775
|
+
packageName,
|
|
6776
|
+
installedName: packageJson.name,
|
|
6777
|
+
installedVersion: packageJson.version,
|
|
6778
|
+
projectPackage
|
|
6779
|
+
});
|
|
6489
6780
|
const dependencyNames = [
|
|
6490
6781
|
...isRecord(packageJson.dependencies) ? Object.keys(packageJson.dependencies) : [],
|
|
6491
6782
|
...isRecord(packageJson.peerDependencies) ? Object.keys(packageJson.peerDependencies) : []
|
|
@@ -6580,7 +6871,7 @@ var verifyDeploymentDeclaration = (deploymentId, value) => {
|
|
|
6580
6871
|
for (const [strategyName, strategyValue] of Object.entries(
|
|
6581
6872
|
value.strategies
|
|
6582
6873
|
)) {
|
|
6583
|
-
if (!strategyName.trim() || !isRecord(strategyValue) || Object.keys(strategyValue).some((key) => !STRATEGY_KEYS.has(key)) || strategyValue.generation !== void 0 && (typeof strategyValue.generation !== "string" || !strategyValue.generation.trim()) || typeof strategyValue.enabled !== "boolean" || !verifyStrategySelection(strategyValue.selection) || !isRecord(strategyValue.config) || Object.keys(strategyValue.config).some(
|
|
6874
|
+
if (!strategyName.trim() || !isRecord(strategyValue) || Object.keys(strategyValue).some((key) => !STRATEGY_KEYS.has(key)) || strategyValue.generation !== void 0 && (typeof strategyValue.generation !== "string" || !strategyValue.generation.trim()) || strategyValue.module !== void 0 && (typeof strategyValue.module !== "string" || !strategyValue.module.trim()) || typeof strategyValue.enabled !== "boolean" || !verifyStrategySelection(strategyValue.selection) || !isRecord(strategyValue.config) || Object.keys(strategyValue.config).some(
|
|
6584
6875
|
(key) => FORBIDDEN_CONFIG_KEYS.has(key)
|
|
6585
6876
|
) || !INTERVALS.has(String(strategyValue.config.INTERVAL)) || !["crypto", "tradfi"].includes(String(strategyValue.config.UNIVERSE))) {
|
|
6586
6877
|
throw new Error(
|
|
@@ -6614,9 +6905,9 @@ var resolveStrategyComposition = async ({
|
|
|
6614
6905
|
packageManifest
|
|
6615
6906
|
}) => {
|
|
6616
6907
|
const [strategyEntry, strategyCreator, pluginSource] = await Promise.all([
|
|
6617
|
-
getStrategyEntry(strategyName, projectRoot),
|
|
6618
|
-
getStrategyCreator(strategyName, projectRoot),
|
|
6619
|
-
getStrategyPluginSource(strategyName, projectRoot)
|
|
6908
|
+
getStrategyEntry(strategyName, projectRoot, declaration.module),
|
|
6909
|
+
getStrategyCreator(strategyName, projectRoot, declaration.module),
|
|
6910
|
+
getStrategyPluginSource(strategyName, projectRoot, declaration.module)
|
|
6620
6911
|
]);
|
|
6621
6912
|
if (!strategyEntry || !strategyCreator) {
|
|
6622
6913
|
throw new Error(`Unknown strategy: ${strategyName}`);
|
|
@@ -6666,6 +6957,7 @@ var resolveStrategyComposition = async ({
|
|
|
6666
6957
|
});
|
|
6667
6958
|
return {
|
|
6668
6959
|
strategyName,
|
|
6960
|
+
strategyModule: pluginSource ?? strategyPackage.name,
|
|
6669
6961
|
strategyRevision: computeStrategyRevision({
|
|
6670
6962
|
strategyName,
|
|
6671
6963
|
strategyPackage: strategyPackage.name,
|
|
@@ -6854,11 +7146,12 @@ var loadResolvedRuntimeStrategies = async ({
|
|
|
6854
7146
|
};
|
|
6855
7147
|
var getRuntimeStrategyPackageMetadata = async ({
|
|
6856
7148
|
strategyName,
|
|
6857
|
-
projectRoot
|
|
7149
|
+
projectRoot,
|
|
7150
|
+
strategyModule
|
|
6858
7151
|
}) => {
|
|
6859
7152
|
const [packageManifest, pluginSource] = await Promise.all([
|
|
6860
7153
|
readRuntimePackageManifest(projectRoot),
|
|
6861
|
-
getStrategyPluginSource(strategyName, projectRoot)
|
|
7154
|
+
getStrategyPluginSource(strategyName, projectRoot, strategyModule)
|
|
6862
7155
|
]);
|
|
6863
7156
|
const strategyPackage = await resolveStrategyPackage({
|
|
6864
7157
|
pluginSource: pluginSource ?? null,
|
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
loadResolvedRuntimeStrategies,
|
|
9
9
|
resolveRuntimeComposition,
|
|
10
10
|
verifyRuntimeDeclaration
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-K2YQ3MQC.mjs";
|
|
12
|
+
import "./chunk-VQSGH7YA.mjs";
|
|
13
|
+
import "./chunk-UITD6LG6.mjs";
|
|
14
14
|
import "./chunk-LZDXRXIU.mjs";
|
|
15
15
|
import "./chunk-Y6FXYEAI.mjs";
|
|
16
16
|
export {
|
package/dist/runtimeTrades.d.mts
CHANGED
|
@@ -19,13 +19,14 @@ declare const takeClosedPnlMatch: ({ exactByOrderLinkId, exactByOrderId, symbolB
|
|
|
19
19
|
trade: RuntimeTradeRecord;
|
|
20
20
|
}) => ClosedPnlRecordWithOrderLinkId | null;
|
|
21
21
|
|
|
22
|
-
declare const buildExchangeFallbackRuntimeTrades: ({ entryRows, closedPnlRows, openPositions, strategyNames, existingTrades, endTime, }: {
|
|
22
|
+
declare const buildExchangeFallbackRuntimeTrades: ({ entryRows, closedPnlRows, openPositions, strategyNames, existingTrades, endTime, scope, }: {
|
|
23
23
|
entryRows: ExchangeEntryRecord[];
|
|
24
24
|
closedPnlRows: ClosedPnlRecordWithOrderLinkId[];
|
|
25
25
|
openPositions: PositionPnlSnapshot[];
|
|
26
26
|
strategyNames: string[];
|
|
27
27
|
existingTrades: RuntimeTradeRecord[];
|
|
28
28
|
endTime: number;
|
|
29
|
+
scope?: Pick<RuntimeTradeRecord, "accountId" | "deploymentId" | "universe">;
|
|
29
30
|
}) => RuntimeTradeRecord[];
|
|
30
31
|
|
|
31
32
|
export { type ClosedPnlRecordWithOrderLinkId, buildExchangeFallbackRuntimeTrades, takeClosedPnlMatch, takeExactClosedPnlMatch };
|
package/dist/runtimeTrades.d.ts
CHANGED
|
@@ -19,13 +19,14 @@ declare const takeClosedPnlMatch: ({ exactByOrderLinkId, exactByOrderId, symbolB
|
|
|
19
19
|
trade: RuntimeTradeRecord;
|
|
20
20
|
}) => ClosedPnlRecordWithOrderLinkId | null;
|
|
21
21
|
|
|
22
|
-
declare const buildExchangeFallbackRuntimeTrades: ({ entryRows, closedPnlRows, openPositions, strategyNames, existingTrades, endTime, }: {
|
|
22
|
+
declare const buildExchangeFallbackRuntimeTrades: ({ entryRows, closedPnlRows, openPositions, strategyNames, existingTrades, endTime, scope, }: {
|
|
23
23
|
entryRows: ExchangeEntryRecord[];
|
|
24
24
|
closedPnlRows: ClosedPnlRecordWithOrderLinkId[];
|
|
25
25
|
openPositions: PositionPnlSnapshot[];
|
|
26
26
|
strategyNames: string[];
|
|
27
27
|
existingTrades: RuntimeTradeRecord[];
|
|
28
28
|
endTime: number;
|
|
29
|
+
scope?: Pick<RuntimeTradeRecord, "accountId" | "deploymentId" | "universe">;
|
|
29
30
|
}) => RuntimeTradeRecord[];
|
|
30
31
|
|
|
31
32
|
export { type ClosedPnlRecordWithOrderLinkId, buildExchangeFallbackRuntimeTrades, takeClosedPnlMatch, takeExactClosedPnlMatch };
|
package/dist/runtimeTrades.js
CHANGED
|
@@ -190,7 +190,8 @@ var buildExchangeFallbackRuntimeTrades = ({
|
|
|
190
190
|
openPositions,
|
|
191
191
|
strategyNames,
|
|
192
192
|
existingTrades,
|
|
193
|
-
endTime
|
|
193
|
+
endTime,
|
|
194
|
+
scope
|
|
194
195
|
}) => {
|
|
195
196
|
if (!entryRows.length && !closedPnlRows.length) return [];
|
|
196
197
|
const strategyNameByOrderId = new Map(
|
|
@@ -245,6 +246,7 @@ var buildExchangeFallbackRuntimeTrades = ({
|
|
|
245
246
|
const entryPrice = typeof entry.entryPrice === "number" && Number.isFinite(entry.entryPrice) ? entry.entryPrice : typeof closed?.entryPrice === "number" && Number.isFinite(closed.entryPrice) ? closed.entryPrice : null;
|
|
246
247
|
if (entryPrice == null) return null;
|
|
247
248
|
return {
|
|
249
|
+
...scope,
|
|
248
250
|
orderId: runtimeOrderId,
|
|
249
251
|
strategy,
|
|
250
252
|
symbol: entry.symbol,
|
|
@@ -287,6 +289,7 @@ var buildExchangeFallbackRuntimeTrades = ({
|
|
|
287
289
|
return null;
|
|
288
290
|
}
|
|
289
291
|
return {
|
|
292
|
+
...scope,
|
|
290
293
|
orderId: runtimeOrderId,
|
|
291
294
|
strategy,
|
|
292
295
|
symbol: row.symbol,
|
package/dist/runtimeTrades.mjs
CHANGED
package/dist/strategies.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from '@tradejs/core/strategies';
|
|
2
2
|
export { AiChatMessage, DEFAULT_AI_MODEL, InvokeAiChatOptions, MAX_AI_SERIES_POINTS, askAI, buildAiHumanPrompt, buildAiPayload, buildAiPrompts, buildAiSystemPrompt, buildCompactAiIndicatorsSnapshot, getDeterministicAiGateContext, getOpenRouterModelKwargs, invokeAiChat, resetAiRuntimeCache, runAiPrompt, runAiPromptLocal, trimSeriesDeep } from './ai.mjs';
|
|
3
|
-
export { e as ensureIndicatorPluginsLoaded, a as ensureStrategyPluginsLoaded, g as getAvailableStrategyNames, b as getRegisteredManifests, c as getRegisteredStrategies, d as getStrategyCreator, f as getStrategyDefaults, h as getStrategyManifest, i as getStrategyPluginSource, j as isKnownStrategy, r as registerStrategyEntries, k as resetStrategyRegistryCache, s as strategies } from './registry-
|
|
3
|
+
export { e as ensureIndicatorPluginsLoaded, a as ensureStrategyPluginsLoaded, g as getAvailableStrategyNames, b as getRegisteredManifests, c as getRegisteredStrategies, d as getStrategyCreator, f as getStrategyDefaults, h as getStrategyManifest, i as getStrategyPluginSource, j as isKnownStrategy, r as registerStrategyEntries, k as resetStrategyRegistryCache, s as strategies } from './registry-3TsO1Ff1.mjs';
|
|
4
4
|
import { StrategyConfig, CreateStrategyCore, StrategyManifest, StrategyCreator, RuntimeStrategyConfigSnapshot, Signal, Direction, StrategyRuntimeMlOptions, StrategyRuntimeAiOptions, Connector, Tp, MarketFeatureInterval, StrategyEntrySignalContext } from '@tradejs/types';
|
|
5
5
|
import { TradejsConfigOnBarHook, TradejsConfigBeforeSignalsHook } from '@tradejs/core/config';
|
|
6
6
|
|
|
@@ -79,6 +79,18 @@ declare const validateEntryProtectionAtArrival: ({ direction, signalPrice, bid,
|
|
|
79
79
|
}) => void;
|
|
80
80
|
declare const executeEntryOrder: ({ connector, userName, symbol, direction, qty, currentPrice, timestamp, takeProfits, stopLossPrice, positionIntent, signal, beforePlaceOrder, recordRuntimeTrade, leverage, }: ExecuteEntryOrderParams) => Promise<number>;
|
|
81
81
|
|
|
82
|
+
declare const preloadBinanceMarketContextForWindow: (params: {
|
|
83
|
+
startMs: number;
|
|
84
|
+
endMs: number;
|
|
85
|
+
interval: MarketFeatureInterval;
|
|
86
|
+
maxAgeMs?: number;
|
|
87
|
+
timeoutMs?: number;
|
|
88
|
+
chunkMs?: number;
|
|
89
|
+
abortSignal?: AbortSignal;
|
|
90
|
+
}) => Promise<{
|
|
91
|
+
tradeFlowRows: number;
|
|
92
|
+
breadthRows: number;
|
|
93
|
+
}>;
|
|
82
94
|
declare const enrichSignalWithBinanceMarketContext: (params: {
|
|
83
95
|
signal: Signal;
|
|
84
96
|
env: string;
|
|
@@ -200,4 +212,4 @@ interface CreateCloseAllOnGlobalProfitBeforeSignalsHookParams {
|
|
|
200
212
|
}
|
|
201
213
|
declare const createCloseAllOnGlobalProfitBeforeSignalsHook: ({ getStrategyDefaultConfig, profitRiskMultiplier, }?: CreateCloseAllOnGlobalProfitBeforeSignalsHookParams) => TradejsConfigBeforeSignalsHook;
|
|
202
214
|
|
|
203
|
-
export { BINANCE_BREADTH_UNIVERSE_KEYS, type BinanceBreadthUniverseDefinition, type BinanceBreadthUniverseKey, type BinanceBreadthUniverseSnapshot, type HyperliquidPerpUniverseSnapshot, type HyperliquidWhaleRegistrySnapshot, buildBinanceBreadthUniverseSnapshot, closeOppositePositionsBeforeOpen, createCloseAllOnGlobalProfitBeforeSignalsHook, createCloseOppositeBeforePlaceOrderHook, createMoveStopToBreakEvenAfterCoreDecisionHook, createMoveStopToBreakEvenOnBarHook, createStrategyRuntime, enrichSignalWithAi, enrichSignalWithBinanceMarketContext, enrichSignalWithCoinMarketCapContext, enrichSignalWithHyperliquidWhaleContext, enrichSignalWithMl, enrichSignalWithMlAi, executeEntryOrder, getBinanceBreadthUniverseSnapshot, getBinanceBreadthUniverses, getHyperliquidPerpSymbols, getHyperliquidPerpUniverseSnapshot, getHyperliquidWhaleAddresses, getHyperliquidWhaleRegistrySnapshot, getOrderArrivalSnapshot, getPrimaryBinanceBreadthUniverse, isTrackedHyperliquidPerp, isTrackedHyperliquidWhale, resolveHyperliquidPerpFromSignalSymbol, resolveStrategyConfig, validateEntryProtectionAtArrival };
|
|
215
|
+
export { BINANCE_BREADTH_UNIVERSE_KEYS, type BinanceBreadthUniverseDefinition, type BinanceBreadthUniverseKey, type BinanceBreadthUniverseSnapshot, type HyperliquidPerpUniverseSnapshot, type HyperliquidWhaleRegistrySnapshot, buildBinanceBreadthUniverseSnapshot, closeOppositePositionsBeforeOpen, createCloseAllOnGlobalProfitBeforeSignalsHook, createCloseOppositeBeforePlaceOrderHook, createMoveStopToBreakEvenAfterCoreDecisionHook, createMoveStopToBreakEvenOnBarHook, createStrategyRuntime, enrichSignalWithAi, enrichSignalWithBinanceMarketContext, enrichSignalWithCoinMarketCapContext, enrichSignalWithHyperliquidWhaleContext, enrichSignalWithMl, enrichSignalWithMlAi, executeEntryOrder, getBinanceBreadthUniverseSnapshot, getBinanceBreadthUniverses, getHyperliquidPerpSymbols, getHyperliquidPerpUniverseSnapshot, getHyperliquidWhaleAddresses, getHyperliquidWhaleRegistrySnapshot, getOrderArrivalSnapshot, getPrimaryBinanceBreadthUniverse, isTrackedHyperliquidPerp, isTrackedHyperliquidWhale, preloadBinanceMarketContextForWindow, resolveHyperliquidPerpFromSignalSymbol, resolveStrategyConfig, validateEntryProtectionAtArrival };
|