@tradejs/node 3.1.27 → 3.1.28-beta.251
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
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
resolveStrategyPolicyProfile,
|
|
6
6
|
runAiPromptLocal,
|
|
7
7
|
setStrategyRuntimeFactory
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-UITD6LG6.mjs";
|
|
9
9
|
import {
|
|
10
10
|
getTradejsProjectCwd,
|
|
11
11
|
loadTradejsConfig
|
|
@@ -318,6 +318,8 @@ var getPrimaryBinanceBreadthUniverse = () => getBinanceBreadthUniverses().find((
|
|
|
318
318
|
|
|
319
319
|
// src/strategyHelpers/binanceMarketContext.ts
|
|
320
320
|
import {
|
|
321
|
+
getMarketBreadthRows,
|
|
322
|
+
getMarketTradeFlowRows,
|
|
321
323
|
getLatestMarketBreadth,
|
|
322
324
|
getLatestMarketTradeFlow
|
|
323
325
|
} from "@tradejs/infra/timescale/marketContext";
|
|
@@ -338,9 +340,50 @@ var DEFAULT_MAX_AGE_BY_INTERVAL = {
|
|
|
338
340
|
"15m": 30 * 6e4,
|
|
339
341
|
"1h": 2 * 60 * 6e4
|
|
340
342
|
};
|
|
343
|
+
var MARKET_CONTEXT_PRELOAD_CHUNK_MS = 7 * 24 * 60 * 6e4;
|
|
341
344
|
var binanceMarketContextUnavailable = false;
|
|
342
345
|
var referenceRowsCache = /* @__PURE__ */ new Map();
|
|
343
346
|
var breadthCache = /* @__PURE__ */ new Map();
|
|
347
|
+
var TRADE_FLOW_NUMERIC_FIELDS = [
|
|
348
|
+
"trades",
|
|
349
|
+
"buyBaseVolume",
|
|
350
|
+
"sellBaseVolume",
|
|
351
|
+
"buyQuoteVolume",
|
|
352
|
+
"sellQuoteVolume",
|
|
353
|
+
"netBaseDelta",
|
|
354
|
+
"netQuoteDelta",
|
|
355
|
+
"buyPressurePct"
|
|
356
|
+
];
|
|
357
|
+
var BREADTH_COMMON_NUMERIC_FIELDS = [
|
|
358
|
+
"symbolsCount",
|
|
359
|
+
"advancers",
|
|
360
|
+
"decliners",
|
|
361
|
+
"unchanged",
|
|
362
|
+
"advanceDeclineRatio",
|
|
363
|
+
"pctAboveMa20",
|
|
364
|
+
"pctAboveMa50",
|
|
365
|
+
"equalWeightedReturn",
|
|
366
|
+
"volumeWeightedReturn",
|
|
367
|
+
"dispersion"
|
|
368
|
+
];
|
|
369
|
+
var BREADTH_REGIME_NUMERIC_FIELDS = [
|
|
370
|
+
"btcReturn1h",
|
|
371
|
+
"btcReturn4h",
|
|
372
|
+
"btcReturn24h",
|
|
373
|
+
"altBasketReturn1h",
|
|
374
|
+
"altBasketReturn4h",
|
|
375
|
+
"altBasketReturn24h",
|
|
376
|
+
"btcVsAltReturn1h",
|
|
377
|
+
"btcVsAltReturn4h",
|
|
378
|
+
"btcVsAltReturn24h",
|
|
379
|
+
"btcTurnoverShare1h",
|
|
380
|
+
"btcTurnoverShare24h",
|
|
381
|
+
"btcTurnoverShareChange24h",
|
|
382
|
+
"altVolToBtcVol24h",
|
|
383
|
+
"altDispersion24h"
|
|
384
|
+
];
|
|
385
|
+
var preloadedTradeFlowBySymbol = null;
|
|
386
|
+
var preloadedBreadthByUniverse = null;
|
|
344
387
|
var parseEnabledFlag = (value, env) => {
|
|
345
388
|
const normalized = String(value ?? "").trim().toLowerCase();
|
|
346
389
|
if (!normalized)
|
|
@@ -376,6 +419,240 @@ var hasBaseContext = (signal) => Boolean(
|
|
|
376
419
|
signal.additionalIndicators?.baseContext && typeof signal.additionalIndicators.baseContext === "object" && !Array.isArray(signal.additionalIndicators.baseContext)
|
|
377
420
|
);
|
|
378
421
|
var isBinanceMarketContextEnabled = (env) => parseEnabledFlag(process.env.BINANCE_MARKET_CONTEXT_ENABLED, env);
|
|
422
|
+
var latestIndexAtOrBefore = (timestamps, timestamp) => {
|
|
423
|
+
if (!timestamps?.length) return -1;
|
|
424
|
+
let low = 0;
|
|
425
|
+
let high = timestamps.length - 1;
|
|
426
|
+
let match = -1;
|
|
427
|
+
while (low <= high) {
|
|
428
|
+
const middle = Math.floor((low + high) / 2);
|
|
429
|
+
const rowTimestamp = timestamps[middle];
|
|
430
|
+
if (rowTimestamp == null) break;
|
|
431
|
+
if (rowTimestamp <= timestamp) {
|
|
432
|
+
match = middle;
|
|
433
|
+
low = middle + 1;
|
|
434
|
+
} else {
|
|
435
|
+
high = middle - 1;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return match;
|
|
439
|
+
};
|
|
440
|
+
var latestChunkAtOrBefore = (chunks, timestamp) => {
|
|
441
|
+
if (!chunks?.length) return null;
|
|
442
|
+
let low = 0;
|
|
443
|
+
let high = chunks.length - 1;
|
|
444
|
+
let match = null;
|
|
445
|
+
while (low <= high) {
|
|
446
|
+
const middle = Math.floor((low + high) / 2);
|
|
447
|
+
const chunk = chunks[middle];
|
|
448
|
+
const firstTimestamp = chunk?.timestamps[0];
|
|
449
|
+
if (!chunk || firstTimestamp == null) break;
|
|
450
|
+
if (firstTimestamp <= timestamp) {
|
|
451
|
+
match = chunk;
|
|
452
|
+
low = middle + 1;
|
|
453
|
+
} else {
|
|
454
|
+
high = middle - 1;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
return match;
|
|
458
|
+
};
|
|
459
|
+
var createNumericColumns = (fields, length) => Object.fromEntries(
|
|
460
|
+
fields.map((field) => [field, new Float64Array(length)])
|
|
461
|
+
);
|
|
462
|
+
var packedNumber = (value) => {
|
|
463
|
+
const numeric = typeof value === "number" ? value : Number(value);
|
|
464
|
+
return Number.isFinite(numeric) ? numeric : Number.NaN;
|
|
465
|
+
};
|
|
466
|
+
var unpackedNumber = (value) => value == null || Number.isNaN(value) ? null : value;
|
|
467
|
+
var packTradeFlowRows = (rows) => {
|
|
468
|
+
const counts = /* @__PURE__ */ new Map();
|
|
469
|
+
for (const row of rows) {
|
|
470
|
+
counts.set(row.symbol, (counts.get(row.symbol) ?? 0) + 1);
|
|
471
|
+
}
|
|
472
|
+
const packed = /* @__PURE__ */ new Map();
|
|
473
|
+
for (const [symbol, length] of counts) {
|
|
474
|
+
packed.set(symbol, {
|
|
475
|
+
symbol,
|
|
476
|
+
interval: rows.find((row) => row.symbol === symbol)?.interval ?? "15m",
|
|
477
|
+
timestamps: new Float64Array(length),
|
|
478
|
+
columns: createNumericColumns(TRADE_FLOW_NUMERIC_FIELDS, length)
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
const offsets = /* @__PURE__ */ new Map();
|
|
482
|
+
for (const row of rows) {
|
|
483
|
+
const target = packed.get(row.symbol);
|
|
484
|
+
if (!target) continue;
|
|
485
|
+
const index = offsets.get(row.symbol) ?? 0;
|
|
486
|
+
target.timestamps[index] = row.ts.getTime();
|
|
487
|
+
for (const field of TRADE_FLOW_NUMERIC_FIELDS) {
|
|
488
|
+
target.columns[field][index] = packedNumber(row[field]);
|
|
489
|
+
}
|
|
490
|
+
offsets.set(row.symbol, index + 1);
|
|
491
|
+
}
|
|
492
|
+
return packed;
|
|
493
|
+
};
|
|
494
|
+
var packBreadthRows = (rows, primaryUniverse) => {
|
|
495
|
+
const counts = /* @__PURE__ */ new Map();
|
|
496
|
+
for (const row of rows) {
|
|
497
|
+
counts.set(row.universe, (counts.get(row.universe) ?? 0) + 1);
|
|
498
|
+
}
|
|
499
|
+
const packed = /* @__PURE__ */ new Map();
|
|
500
|
+
for (const [universe, length] of counts) {
|
|
501
|
+
packed.set(universe, {
|
|
502
|
+
universe,
|
|
503
|
+
interval: rows.find((row) => row.universe === universe)?.interval ?? "15m",
|
|
504
|
+
timestamps: new Float64Array(length),
|
|
505
|
+
commonColumns: createNumericColumns(
|
|
506
|
+
BREADTH_COMMON_NUMERIC_FIELDS,
|
|
507
|
+
length
|
|
508
|
+
),
|
|
509
|
+
...universe === primaryUniverse ? {
|
|
510
|
+
regimeColumns: createNumericColumns(
|
|
511
|
+
BREADTH_REGIME_NUMERIC_FIELDS,
|
|
512
|
+
length
|
|
513
|
+
),
|
|
514
|
+
regimes: new Array(length)
|
|
515
|
+
} : {}
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
const offsets = /* @__PURE__ */ new Map();
|
|
519
|
+
for (const row of rows) {
|
|
520
|
+
const target = packed.get(row.universe);
|
|
521
|
+
if (!target) continue;
|
|
522
|
+
const index = offsets.get(row.universe) ?? 0;
|
|
523
|
+
target.timestamps[index] = row.ts.getTime();
|
|
524
|
+
for (const field of BREADTH_COMMON_NUMERIC_FIELDS) {
|
|
525
|
+
target.commonColumns[field][index] = packedNumber(row[field]);
|
|
526
|
+
}
|
|
527
|
+
if (target.regimeColumns) {
|
|
528
|
+
for (const field of BREADTH_REGIME_NUMERIC_FIELDS) {
|
|
529
|
+
target.regimeColumns[field][index] = packedNumber(row[field]);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
if (target.regimes) target.regimes[index] = row.btcAltRegime;
|
|
533
|
+
offsets.set(row.universe, index + 1);
|
|
534
|
+
}
|
|
535
|
+
return packed;
|
|
536
|
+
};
|
|
537
|
+
var appendPackedChunks = (target, source) => {
|
|
538
|
+
for (const [key, rows] of source) {
|
|
539
|
+
const chunks = target.get(key) ?? [];
|
|
540
|
+
chunks.push(rows);
|
|
541
|
+
target.set(key, chunks);
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
var unpackTradeFlowRow = (chunks, timestamp) => {
|
|
545
|
+
const rows = latestChunkAtOrBefore(chunks, timestamp);
|
|
546
|
+
const index = latestIndexAtOrBefore(rows?.timestamps, timestamp);
|
|
547
|
+
if (!rows || index < 0) return null;
|
|
548
|
+
return {
|
|
549
|
+
symbol: rows.symbol,
|
|
550
|
+
interval: rows.interval,
|
|
551
|
+
ts: new Date(rows.timestamps[index]),
|
|
552
|
+
trades: unpackedNumber(rows.columns.trades[index]) ?? 0,
|
|
553
|
+
buyBaseVolume: unpackedNumber(rows.columns.buyBaseVolume[index]),
|
|
554
|
+
sellBaseVolume: unpackedNumber(rows.columns.sellBaseVolume[index]),
|
|
555
|
+
buyQuoteVolume: unpackedNumber(rows.columns.buyQuoteVolume[index]),
|
|
556
|
+
sellQuoteVolume: unpackedNumber(rows.columns.sellQuoteVolume[index]),
|
|
557
|
+
netBaseDelta: unpackedNumber(rows.columns.netBaseDelta[index]),
|
|
558
|
+
netQuoteDelta: unpackedNumber(rows.columns.netQuoteDelta[index]),
|
|
559
|
+
buyPressurePct: unpackedNumber(rows.columns.buyPressurePct[index])
|
|
560
|
+
};
|
|
561
|
+
};
|
|
562
|
+
var unpackBreadthRow = (chunks, timestamp) => {
|
|
563
|
+
const rows = latestChunkAtOrBefore(chunks, timestamp);
|
|
564
|
+
const index = latestIndexAtOrBefore(rows?.timestamps, timestamp);
|
|
565
|
+
if (!rows || index < 0) return null;
|
|
566
|
+
const commonNumeric = Object.fromEntries(
|
|
567
|
+
BREADTH_COMMON_NUMERIC_FIELDS.map((field) => [
|
|
568
|
+
field,
|
|
569
|
+
unpackedNumber(rows.commonColumns[field][index])
|
|
570
|
+
])
|
|
571
|
+
);
|
|
572
|
+
const regimeNumeric = Object.fromEntries(
|
|
573
|
+
BREADTH_REGIME_NUMERIC_FIELDS.map((field) => [
|
|
574
|
+
field,
|
|
575
|
+
unpackedNumber(rows.regimeColumns?.[field][index])
|
|
576
|
+
])
|
|
577
|
+
);
|
|
578
|
+
return {
|
|
579
|
+
universe: rows.universe,
|
|
580
|
+
interval: rows.interval,
|
|
581
|
+
ts: new Date(rows.timestamps[index]),
|
|
582
|
+
...commonNumeric,
|
|
583
|
+
...regimeNumeric,
|
|
584
|
+
symbolsCount: commonNumeric.symbolsCount ?? 0,
|
|
585
|
+
advancers: commonNumeric.advancers ?? 0,
|
|
586
|
+
decliners: commonNumeric.decliners ?? 0,
|
|
587
|
+
unchanged: commonNumeric.unchanged ?? 0,
|
|
588
|
+
btcAltRegime: rows.regimes?.[index] ?? null
|
|
589
|
+
};
|
|
590
|
+
};
|
|
591
|
+
var toAsOfRow = (row, timestamp, maxAgeMs) => {
|
|
592
|
+
if (!row) return null;
|
|
593
|
+
const ageMs = timestamp - row.ts.getTime();
|
|
594
|
+
return {
|
|
595
|
+
...row,
|
|
596
|
+
ageMs: Number.isFinite(ageMs) ? ageMs : null,
|
|
597
|
+
stale: !Number.isFinite(ageMs) || ageMs < 0 || ageMs > maxAgeMs
|
|
598
|
+
};
|
|
599
|
+
};
|
|
600
|
+
var preloadBinanceMarketContextForWindow = async (params) => {
|
|
601
|
+
const maxAgeMs = params.maxAgeMs ?? DEFAULT_MAX_AGE_BY_INTERVAL[params.interval];
|
|
602
|
+
const referenceSymbols = getReferenceSymbols();
|
|
603
|
+
const breadthDefinitions = getBinanceBreadthUniverses();
|
|
604
|
+
const breadthUniverses = breadthDefinitions.map(({ universe }) => universe);
|
|
605
|
+
const primaryBreadthUniverse = breadthDefinitions.find(
|
|
606
|
+
({ key }) => key === "top30"
|
|
607
|
+
).universe;
|
|
608
|
+
const timeoutMs = params.timeoutMs ?? 5 * 6e4;
|
|
609
|
+
const chunkMs = params.chunkMs ?? MARKET_CONTEXT_PRELOAD_CHUNK_MS;
|
|
610
|
+
if (!Number.isSafeInteger(chunkMs) || chunkMs <= 0) {
|
|
611
|
+
throw new Error(`Invalid market context preload chunk: ${chunkMs}`);
|
|
612
|
+
}
|
|
613
|
+
const packedTradeFlow = /* @__PURE__ */ new Map();
|
|
614
|
+
const packedBreadth = /* @__PURE__ */ new Map();
|
|
615
|
+
let tradeFlowRowsCount = 0;
|
|
616
|
+
let breadthRowsCount = 0;
|
|
617
|
+
let fromMs = params.startMs - maxAgeMs;
|
|
618
|
+
while (fromMs <= params.endMs) {
|
|
619
|
+
const toMs = Math.min(params.endMs, fromMs + chunkMs - 1);
|
|
620
|
+
const [tradeFlowRows, breadthRows] = await Promise.all([
|
|
621
|
+
getMarketTradeFlowRows({
|
|
622
|
+
symbols: referenceSymbols,
|
|
623
|
+
interval: params.interval,
|
|
624
|
+
fromMs,
|
|
625
|
+
toMs,
|
|
626
|
+
timeoutMs,
|
|
627
|
+
...params.abortSignal ? { signal: params.abortSignal } : {}
|
|
628
|
+
}),
|
|
629
|
+
getMarketBreadthRows({
|
|
630
|
+
universes: breadthUniverses,
|
|
631
|
+
interval: params.interval,
|
|
632
|
+
fromMs,
|
|
633
|
+
toMs,
|
|
634
|
+
timeoutMs,
|
|
635
|
+
...params.abortSignal ? { signal: params.abortSignal } : {}
|
|
636
|
+
})
|
|
637
|
+
]);
|
|
638
|
+
tradeFlowRowsCount += tradeFlowRows.length;
|
|
639
|
+
breadthRowsCount += breadthRows.length;
|
|
640
|
+
appendPackedChunks(packedTradeFlow, packTradeFlowRows(tradeFlowRows));
|
|
641
|
+
appendPackedChunks(
|
|
642
|
+
packedBreadth,
|
|
643
|
+
packBreadthRows(breadthRows, primaryBreadthUniverse)
|
|
644
|
+
);
|
|
645
|
+
fromMs = toMs + 1;
|
|
646
|
+
}
|
|
647
|
+
preloadedTradeFlowBySymbol = packedTradeFlow;
|
|
648
|
+
preloadedBreadthByUniverse = packedBreadth;
|
|
649
|
+
referenceRowsCache.clear();
|
|
650
|
+
breadthCache.clear();
|
|
651
|
+
return {
|
|
652
|
+
tradeFlowRows: tradeFlowRowsCount,
|
|
653
|
+
breadthRows: breadthRowsCount
|
|
654
|
+
};
|
|
655
|
+
};
|
|
379
656
|
var toTradeFlowContext = (row, interval) => row ? {
|
|
380
657
|
source: "binance_agg_trades",
|
|
381
658
|
interval,
|
|
@@ -398,6 +675,24 @@ var getCachedReferenceRows = ({
|
|
|
398
675
|
maxAgeMs,
|
|
399
676
|
abortSignal
|
|
400
677
|
}) => {
|
|
678
|
+
if (preloadedTradeFlowBySymbol) {
|
|
679
|
+
return Promise.resolve(
|
|
680
|
+
referenceSymbols.map((symbol) => ({
|
|
681
|
+
symbol,
|
|
682
|
+
tradeFlow: toTradeFlowContext(
|
|
683
|
+
toAsOfRow(
|
|
684
|
+
unpackTradeFlowRow(
|
|
685
|
+
preloadedTradeFlowBySymbol?.get(symbol),
|
|
686
|
+
timestamp
|
|
687
|
+
),
|
|
688
|
+
timestamp,
|
|
689
|
+
maxAgeMs
|
|
690
|
+
),
|
|
691
|
+
interval
|
|
692
|
+
)
|
|
693
|
+
}))
|
|
694
|
+
);
|
|
695
|
+
}
|
|
401
696
|
const key = `${referenceSymbols.join(",")}:${interval}:${timestamp}:${maxAgeMs}`;
|
|
402
697
|
const cached = referenceRowsCache.get(key);
|
|
403
698
|
if (cached) return cached;
|
|
@@ -427,6 +722,18 @@ var getCachedBreadth = ({
|
|
|
427
722
|
maxAgeMs,
|
|
428
723
|
abortSignal
|
|
429
724
|
}) => {
|
|
725
|
+
if (preloadedBreadthByUniverse) {
|
|
726
|
+
return Promise.resolve(
|
|
727
|
+
toAsOfRow(
|
|
728
|
+
unpackBreadthRow(
|
|
729
|
+
preloadedBreadthByUniverse.get(breadthUniverse),
|
|
730
|
+
timestamp
|
|
731
|
+
),
|
|
732
|
+
timestamp,
|
|
733
|
+
maxAgeMs
|
|
734
|
+
)
|
|
735
|
+
);
|
|
736
|
+
}
|
|
430
737
|
const key = `${breadthUniverse}:${interval}:${timestamp}:${maxAgeMs}`;
|
|
431
738
|
const cached = breadthCache.get(key);
|
|
432
739
|
if (cached) return cached;
|
|
@@ -639,12 +946,20 @@ var SOURCE_EXCHANGE_LIQUIDITY = "coinmarketcap_exchange_liquidity";
|
|
|
639
946
|
var SOURCE_FEAR_GREED = "coinmarketcap_fear_greed";
|
|
640
947
|
var SOURCE_INDEX = "coinmarketcap_index";
|
|
641
948
|
var DAY_MS = 864e5;
|
|
949
|
+
var MAX_TIMESTAMP_CACHE_ENTRIES = 512;
|
|
642
950
|
var coinMarketCapContextUnavailable = false;
|
|
643
951
|
var globalContextCache = /* @__PURE__ */ new Map();
|
|
644
952
|
var referenceContextCache = /* @__PURE__ */ new Map();
|
|
645
953
|
var exchangeLiquidityContextCache = /* @__PURE__ */ new Map();
|
|
646
954
|
var fearGreedContextCache = /* @__PURE__ */ new Map();
|
|
647
955
|
var indexContextCache = /* @__PURE__ */ new Map();
|
|
956
|
+
var setBoundedCache = (cache, key, value) => {
|
|
957
|
+
if (cache.size >= MAX_TIMESTAMP_CACHE_ENTRIES) {
|
|
958
|
+
const oldestKey = cache.keys().next().value;
|
|
959
|
+
if (oldestKey != null) cache.delete(oldestKey);
|
|
960
|
+
}
|
|
961
|
+
cache.set(key, value);
|
|
962
|
+
};
|
|
648
963
|
var parseEnabledFlag2 = (value, env) => {
|
|
649
964
|
const normalized = String(value ?? "").trim().toLowerCase();
|
|
650
965
|
if (!normalized) {
|
|
@@ -751,7 +1066,7 @@ var getCachedGlobalContext = ({
|
|
|
751
1066
|
maxAgeMs,
|
|
752
1067
|
...abortSignal ? { signal: abortSignal } : {}
|
|
753
1068
|
});
|
|
754
|
-
globalContextCache
|
|
1069
|
+
setBoundedCache(globalContextCache, key, promise);
|
|
755
1070
|
void promise.catch(() => globalContextCache.delete(key));
|
|
756
1071
|
return promise;
|
|
757
1072
|
};
|
|
@@ -771,7 +1086,7 @@ var getCachedReferenceContexts = ({
|
|
|
771
1086
|
maxAgeMs,
|
|
772
1087
|
...abortSignal ? { signal: abortSignal } : {}
|
|
773
1088
|
});
|
|
774
|
-
referenceContextCache
|
|
1089
|
+
setBoundedCache(referenceContextCache, key, promise);
|
|
775
1090
|
void promise.catch(() => referenceContextCache.delete(key));
|
|
776
1091
|
return promise;
|
|
777
1092
|
};
|
|
@@ -790,7 +1105,7 @@ var getCachedExchangeLiquidityContext = ({
|
|
|
790
1105
|
maxAgeMs,
|
|
791
1106
|
...abortSignal ? { signal: abortSignal } : {}
|
|
792
1107
|
});
|
|
793
|
-
exchangeLiquidityContextCache
|
|
1108
|
+
setBoundedCache(exchangeLiquidityContextCache, key, promise);
|
|
794
1109
|
void promise.catch(() => exchangeLiquidityContextCache.delete(key));
|
|
795
1110
|
return promise;
|
|
796
1111
|
};
|
|
@@ -809,7 +1124,7 @@ var getCachedFearGreedContext = ({
|
|
|
809
1124
|
maxAgeMs,
|
|
810
1125
|
...abortSignal ? { signal: abortSignal } : {}
|
|
811
1126
|
});
|
|
812
|
-
fearGreedContextCache
|
|
1127
|
+
setBoundedCache(fearGreedContextCache, key, promise);
|
|
813
1128
|
void promise.catch(() => fearGreedContextCache.delete(key));
|
|
814
1129
|
return promise;
|
|
815
1130
|
};
|
|
@@ -829,7 +1144,7 @@ var getCachedIndexContexts = ({
|
|
|
829
1144
|
maxAgeMs,
|
|
830
1145
|
...abortSignal ? { signal: abortSignal } : {}
|
|
831
1146
|
});
|
|
832
|
-
indexContextCache
|
|
1147
|
+
setBoundedCache(indexContextCache, key, promise);
|
|
833
1148
|
void promise.catch(() => indexContextCache.delete(key));
|
|
834
1149
|
return promise;
|
|
835
1150
|
};
|
|
@@ -1399,7 +1714,7 @@ var signalIntervalToMarketInterval2 = (value) => {
|
|
|
1399
1714
|
var hasBaseContext3 = (signal) => Boolean(
|
|
1400
1715
|
signal.additionalIndicators?.baseContext && typeof signal.additionalIndicators.baseContext === "object" && !Array.isArray(signal.additionalIndicators.baseContext)
|
|
1401
1716
|
);
|
|
1402
|
-
var
|
|
1717
|
+
var setBoundedCache2 = (key, value) => {
|
|
1403
1718
|
if (contextCache.size >= MAX_CACHE_ENTRIES) {
|
|
1404
1719
|
const oldestKey = contextCache.keys().next().value;
|
|
1405
1720
|
if (oldestKey != null) contextCache.delete(oldestKey);
|
|
@@ -1646,7 +1961,7 @@ var loadHyperliquidWhaleFlowContext = async (params) => {
|
|
|
1646
1961
|
whaleRegistryFingerprint: whales.fingerprint,
|
|
1647
1962
|
...params.abortSignal ? { signal: params.abortSignal } : {}
|
|
1648
1963
|
});
|
|
1649
|
-
|
|
1964
|
+
setBoundedCache2(cacheKey, pending);
|
|
1650
1965
|
}
|
|
1651
1966
|
row = await pending;
|
|
1652
1967
|
}
|
|
@@ -3377,20 +3692,23 @@ var buildHookCtx = ({
|
|
|
3377
3692
|
strategyConfig,
|
|
3378
3693
|
env,
|
|
3379
3694
|
isConfigFromBacktest
|
|
3380
|
-
}) =>
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3695
|
+
}) => {
|
|
3696
|
+
const context = {
|
|
3697
|
+
connector,
|
|
3698
|
+
strategyName,
|
|
3699
|
+
userName,
|
|
3700
|
+
symbol
|
|
3701
|
+
};
|
|
3702
|
+
if (universe) context.universe = universe;
|
|
3703
|
+
if (assetClass) context.assetClass = assetClass;
|
|
3704
|
+
if (accountId) context.accountId = accountId;
|
|
3705
|
+
if (deploymentId) context.deploymentId = deploymentId;
|
|
3706
|
+
if (policyProfileId) context.policyProfileId = policyProfileId;
|
|
3707
|
+
context.strategyConfig = strategyConfig;
|
|
3708
|
+
context.env = env;
|
|
3709
|
+
context.isConfigFromBacktest = isConfigFromBacktest;
|
|
3710
|
+
return context;
|
|
3711
|
+
};
|
|
3394
3712
|
var shouldRecordRuntimeJournal = ({
|
|
3395
3713
|
env,
|
|
3396
3714
|
config
|
|
@@ -4716,6 +5034,7 @@ export {
|
|
|
4716
5034
|
getBinanceBreadthUniverseSnapshot,
|
|
4717
5035
|
getBinanceBreadthUniverses,
|
|
4718
5036
|
getPrimaryBinanceBreadthUniverse,
|
|
5037
|
+
preloadBinanceMarketContextForWindow,
|
|
4719
5038
|
enrichSignalWithBinanceMarketContext,
|
|
4720
5039
|
enrichSignalWithCoinMarketCapContext,
|
|
4721
5040
|
getHyperliquidPerpUniverseSnapshot,
|
package/dist/cli.js
CHANGED
|
@@ -954,6 +954,7 @@ var createStrategyRegistryState = () => ({
|
|
|
954
954
|
strategyManifestsMap: /* @__PURE__ */ new Map(),
|
|
955
955
|
strategyEntriesMap: /* @__PURE__ */ new Map(),
|
|
956
956
|
strategySourcesMap: /* @__PURE__ */ new Map(),
|
|
957
|
+
strategyModuleResolutions: /* @__PURE__ */ new Map(),
|
|
957
958
|
pluginsLoadPromise: null
|
|
958
959
|
});
|
|
959
960
|
var registryStateByProjectRoot = sharedStrategyRegistry.registryStateByProjectRoot;
|
|
@@ -1015,7 +1016,7 @@ var validateStrategyEntries = (moduleName, entries, state) => {
|
|
|
1015
1016
|
const strategyName = entry?.manifest?.name;
|
|
1016
1017
|
if (typeof strategyName !== "string" || !strategyName.trim()) {
|
|
1017
1018
|
issues.push(`${entryPath}: manifest.name is required`);
|
|
1018
|
-
} else if (names.has(strategyName) || state
|
|
1019
|
+
} else if (names.has(strategyName) || state?.strategyEntriesMap.has(strategyName)) {
|
|
1019
1020
|
issues.push(`${entryPath}: duplicate strategy ${strategyName}`);
|
|
1020
1021
|
} else {
|
|
1021
1022
|
names.add(strategyName);
|
package/dist/cli.mjs
CHANGED
|
@@ -2,9 +2,9 @@ import { StrategyManifest, StrategyCreator, StrategyRegistryEntry } from '@trade
|
|
|
2
2
|
|
|
3
3
|
declare const ensureStrategyPluginsLoaded: (cwd?: string) => Promise<void>;
|
|
4
4
|
declare const ensureIndicatorPluginsLoaded: (cwd?: string) => Promise<void>;
|
|
5
|
-
declare const getStrategyCreator: (name: string, cwd?: string) => Promise<StrategyCreator | undefined>;
|
|
5
|
+
declare const getStrategyCreator: (name: string, cwd?: string, moduleName?: string) => Promise<StrategyCreator | undefined>;
|
|
6
6
|
declare const getStrategyDefaults: (name: string, cwd?: string) => Promise<StrategyRegistryEntry["defaults"] | undefined>;
|
|
7
|
-
declare const getStrategyPluginSource: (name: string, cwd?: string) => Promise<string | undefined>;
|
|
7
|
+
declare const getStrategyPluginSource: (name: string, cwd?: string, moduleName?: string) => Promise<string | undefined>;
|
|
8
8
|
declare const getAvailableStrategyNames: (cwd?: string) => Promise<string[]>;
|
|
9
9
|
declare const getRegisteredStrategies: (cwd?: string) => Record<string, StrategyCreator>;
|
|
10
10
|
declare const getRegisteredManifests: (cwd?: string) => StrategyManifest[];
|
|
@@ -2,9 +2,9 @@ import { StrategyManifest, StrategyCreator, StrategyRegistryEntry } from '@trade
|
|
|
2
2
|
|
|
3
3
|
declare const ensureStrategyPluginsLoaded: (cwd?: string) => Promise<void>;
|
|
4
4
|
declare const ensureIndicatorPluginsLoaded: (cwd?: string) => Promise<void>;
|
|
5
|
-
declare const getStrategyCreator: (name: string, cwd?: string) => Promise<StrategyCreator | undefined>;
|
|
5
|
+
declare const getStrategyCreator: (name: string, cwd?: string, moduleName?: string) => Promise<StrategyCreator | undefined>;
|
|
6
6
|
declare const getStrategyDefaults: (name: string, cwd?: string) => Promise<StrategyRegistryEntry["defaults"] | undefined>;
|
|
7
|
-
declare const getStrategyPluginSource: (name: string, cwd?: string) => Promise<string | undefined>;
|
|
7
|
+
declare const getStrategyPluginSource: (name: string, cwd?: string, moduleName?: string) => Promise<string | undefined>;
|
|
8
8
|
declare const getAvailableStrategyNames: (cwd?: string) => Promise<string[]>;
|
|
9
9
|
declare const getRegisteredStrategies: (cwd?: string) => Record<string, StrategyCreator>;
|
|
10
10
|
declare const getRegisteredManifests: (cwd?: string) => StrategyManifest[];
|
package/dist/registry.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
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, j as isKnownStrategy, r as registerStrategyEntries, k as resetStrategyRegistryCache, s as strategies } from './registry-
|
|
1
|
+
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, j as isKnownStrategy, r as registerStrategyEntries, k as resetStrategyRegistryCache, s as strategies } from './registry-3TsO1Ff1.mjs';
|
|
2
2
|
import '@tradejs/types';
|
package/dist/registry.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
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, j as isKnownStrategy, r as registerStrategyEntries, k as resetStrategyRegistryCache, s as strategies } from './registry-
|
|
1
|
+
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, j as isKnownStrategy, r as registerStrategyEntries, k as resetStrategyRegistryCache, s as strategies } from './registry-3TsO1Ff1.js';
|
|
2
2
|
import '@tradejs/types';
|