@tradejs/core 2.0.13 → 2.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-HM7WDSPT.mjs → chunk-HVCNGDPT.mjs} +118 -16
- package/dist/indicators.js +118 -16
- package/dist/indicators.mjs +1 -1
- package/dist/strategies.d.mts +7 -1
- package/dist/strategies.d.ts +7 -1
- package/dist/strategies.js +216 -18
- package/dist/strategies.mjs +99 -3
- package/package.json +2 -2
|
@@ -6869,6 +6869,12 @@ var SESSION_WINDOWS = [
|
|
|
6869
6869
|
var FUNDING_WINDOW_STEP_MINUTES = 8 * 60;
|
|
6870
6870
|
var FUNDING_WINDOW_NEARBY_MINUTES = 60;
|
|
6871
6871
|
var SESSION_WINDOW_EDGE_MINUTES = 60;
|
|
6872
|
+
var BASE_INTERVAL_MS = 15 * 6e4;
|
|
6873
|
+
var PSYCHOLOGICAL_LEVEL_WINDOWS = {
|
|
6874
|
+
m15: BASE_INTERVAL_MS,
|
|
6875
|
+
h1: 60 * 6e4,
|
|
6876
|
+
h4: 4 * 60 * 6e4
|
|
6877
|
+
};
|
|
6872
6878
|
var isInsideSession = (minuteUtc, startMinuteUtc, endMinuteUtc) => startMinuteUtc <= endMinuteUtc ? minuteUtc >= startMinuteUtc && minuteUtc < endMinuteUtc : minuteUtc >= startMinuteUtc || minuteUtc < endMinuteUtc;
|
|
6873
6879
|
var buildSessionContext = (timestamp) => {
|
|
6874
6880
|
const date = new Date(timestamp);
|
|
@@ -6900,7 +6906,80 @@ var buildSessionContext = (timestamp) => {
|
|
|
6900
6906
|
isWeekendUtc: dayOfWeekUtc >= 6
|
|
6901
6907
|
};
|
|
6902
6908
|
};
|
|
6909
|
+
var buildUnavailablePsychologicalLevelWindow = () => ({
|
|
6910
|
+
crossed: null,
|
|
6911
|
+
direction: "unknown",
|
|
6912
|
+
level: null,
|
|
6913
|
+
levelsCrossed: null,
|
|
6914
|
+
distanceBeyondLevelBps: null
|
|
6915
|
+
});
|
|
6916
|
+
var buildPsychologicalLevelWindow = (startPrice, endPrice, stepUsd) => {
|
|
6917
|
+
if (!Number.isFinite(startPrice) || !Number.isFinite(endPrice) || !Number.isFinite(stepUsd) || startPrice <= 0 || endPrice <= 0 || stepUsd <= 0) {
|
|
6918
|
+
return buildUnavailablePsychologicalLevelWindow();
|
|
6919
|
+
}
|
|
6920
|
+
if (endPrice === startPrice) {
|
|
6921
|
+
return {
|
|
6922
|
+
crossed: false,
|
|
6923
|
+
direction: "none",
|
|
6924
|
+
level: null,
|
|
6925
|
+
levelsCrossed: 0,
|
|
6926
|
+
distanceBeyondLevelBps: null
|
|
6927
|
+
};
|
|
6928
|
+
}
|
|
6929
|
+
const movingUp = endPrice > startPrice;
|
|
6930
|
+
const firstCrossedLevel = movingUp ? (Math.floor(startPrice / stepUsd) + 1) * stepUsd : (Math.ceil(startPrice / stepUsd) - 1) * stepUsd;
|
|
6931
|
+
const lastCrossedLevel = movingUp ? Math.floor(endPrice / stepUsd) * stepUsd : Math.ceil(endPrice / stepUsd) * stepUsd;
|
|
6932
|
+
const crossed = movingUp ? firstCrossedLevel <= lastCrossedLevel : firstCrossedLevel >= lastCrossedLevel;
|
|
6933
|
+
if (!crossed) {
|
|
6934
|
+
return {
|
|
6935
|
+
crossed: false,
|
|
6936
|
+
direction: "none",
|
|
6937
|
+
level: null,
|
|
6938
|
+
levelsCrossed: 0,
|
|
6939
|
+
distanceBeyondLevelBps: null
|
|
6940
|
+
};
|
|
6941
|
+
}
|
|
6942
|
+
const levelsCrossed = Math.round(Math.abs(lastCrossedLevel - firstCrossedLevel) / stepUsd) + 1;
|
|
6943
|
+
const distanceBeyondLevelBps = Math.abs(endPrice - lastCrossedLevel) / lastCrossedLevel * 1e4;
|
|
6944
|
+
return {
|
|
6945
|
+
crossed: true,
|
|
6946
|
+
direction: movingUp ? "up" : "down",
|
|
6947
|
+
level: lastCrossedLevel,
|
|
6948
|
+
levelsCrossed,
|
|
6949
|
+
distanceBeyondLevelBps
|
|
6950
|
+
};
|
|
6951
|
+
};
|
|
6952
|
+
var buildPsychologicalLevelAssetContext = (candles, stepUsd) => {
|
|
6953
|
+
const endCandle = candles[candles.length - 1];
|
|
6954
|
+
if (!endCandle) {
|
|
6955
|
+
return null;
|
|
6956
|
+
}
|
|
6957
|
+
const candlesByTimestamp = new Map(
|
|
6958
|
+
candles.map((item) => [item.timestamp, item])
|
|
6959
|
+
);
|
|
6960
|
+
const windows = Object.fromEntries(
|
|
6961
|
+
Object.entries(PSYCHOLOGICAL_LEVEL_WINDOWS).map(([window, durationMs]) => {
|
|
6962
|
+
const startCandle = candlesByTimestamp.get(
|
|
6963
|
+
endCandle.timestamp - durationMs
|
|
6964
|
+
);
|
|
6965
|
+
return [
|
|
6966
|
+
window,
|
|
6967
|
+
startCandle ? buildPsychologicalLevelWindow(
|
|
6968
|
+
startCandle.close,
|
|
6969
|
+
endCandle.close,
|
|
6970
|
+
stepUsd
|
|
6971
|
+
) : buildUnavailablePsychologicalLevelWindow()
|
|
6972
|
+
];
|
|
6973
|
+
})
|
|
6974
|
+
);
|
|
6975
|
+
return {
|
|
6976
|
+
source: "aligned_15m_ohlcv",
|
|
6977
|
+
stepUsd,
|
|
6978
|
+
windows
|
|
6979
|
+
};
|
|
6980
|
+
};
|
|
6903
6981
|
var STRUCTURE_LOOKBACK = 80;
|
|
6982
|
+
var BASE_CONTEXT_CANDLE_WINDOW = 256;
|
|
6904
6983
|
var PIVOT_LEFT_RIGHT = 2;
|
|
6905
6984
|
var ZONE_ATR_FACTOR = 0.5;
|
|
6906
6985
|
var PROFILE_BIN_COUNT = 24;
|
|
@@ -8324,12 +8403,12 @@ var buildBaseContextSnapshot = ({
|
|
|
8324
8403
|
candle,
|
|
8325
8404
|
prevCandle,
|
|
8326
8405
|
baseResult,
|
|
8327
|
-
candlesHistory,
|
|
8328
|
-
btcCandlesHistory,
|
|
8329
|
-
ethCandlesHistory = [],
|
|
8330
|
-
closeSeries,
|
|
8331
|
-
volumeSeries,
|
|
8332
|
-
btcCloseSeries,
|
|
8406
|
+
candlesHistory: fullCandlesHistory,
|
|
8407
|
+
btcCandlesHistory: fullBtcCandlesHistory,
|
|
8408
|
+
ethCandlesHistory: fullEthCandlesHistory = [],
|
|
8409
|
+
closeSeries: fullCloseSeries,
|
|
8410
|
+
volumeSeries: fullVolumeSeries,
|
|
8411
|
+
btcCloseSeries: fullBtcCloseSeries,
|
|
8333
8412
|
coinResampledCandles,
|
|
8334
8413
|
btcResampledCandles,
|
|
8335
8414
|
ethResampledCandles,
|
|
@@ -8344,6 +8423,16 @@ var buildBaseContextSnapshot = ({
|
|
|
8344
8423
|
adaptiveChannel: precomputedAdaptiveChannel,
|
|
8345
8424
|
psar: precomputedPsar
|
|
8346
8425
|
}) => {
|
|
8426
|
+
const candlesHistory = fullCandlesHistory.slice(-BASE_CONTEXT_CANDLE_WINDOW);
|
|
8427
|
+
const btcCandlesHistory = fullBtcCandlesHistory.slice(
|
|
8428
|
+
-BASE_CONTEXT_CANDLE_WINDOW
|
|
8429
|
+
);
|
|
8430
|
+
const ethCandlesHistory = fullEthCandlesHistory.slice(
|
|
8431
|
+
-BASE_CONTEXT_CANDLE_WINDOW
|
|
8432
|
+
);
|
|
8433
|
+
const closeSeries = fullCloseSeries.slice(-BASE_CONTEXT_CANDLE_WINDOW);
|
|
8434
|
+
const volumeSeries = fullVolumeSeries.slice(-BASE_CONTEXT_CANDLE_WINDOW);
|
|
8435
|
+
const btcCloseSeries = fullBtcCloseSeries.slice(-BASE_CONTEXT_CANDLE_WINDOW);
|
|
8347
8436
|
const atr2 = toNullable(baseResult.atr);
|
|
8348
8437
|
const bbWidthPct = baseResult.bbUpper != null && baseResult.bbLower != null && baseResult.bbMiddle != null && baseResult.bbMiddle !== 0 ? (baseResult.bbUpper - baseResult.bbLower) / baseResult.bbMiddle * 100 : null;
|
|
8349
8438
|
const atrPctSeries = materializeNumericHistory(
|
|
@@ -8501,6 +8590,18 @@ var buildBaseContextSnapshot = ({
|
|
|
8501
8590
|
coinCandles: candlesHistory,
|
|
8502
8591
|
ethCandles: ethCandlesHistory
|
|
8503
8592
|
}) : null;
|
|
8593
|
+
const btcPsychologicalLevels = buildPsychologicalLevelAssetContext(
|
|
8594
|
+
btcCandlesHistory,
|
|
8595
|
+
1e3
|
|
8596
|
+
);
|
|
8597
|
+
const ethPsychologicalLevels = buildPsychologicalLevelAssetContext(
|
|
8598
|
+
ethCandlesHistory,
|
|
8599
|
+
100
|
|
8600
|
+
);
|
|
8601
|
+
const referencePsychologicalLevels = btcPsychologicalLevels != null || ethPsychologicalLevels != null ? {
|
|
8602
|
+
...btcPsychologicalLevels != null ? { BTCUSDT: btcPsychologicalLevels } : {},
|
|
8603
|
+
...ethPsychologicalLevels != null ? { ETHUSDT: ethPsychologicalLevels } : {}
|
|
8604
|
+
} : null;
|
|
8504
8605
|
const relativeStrength1h = getRelativeChange(
|
|
8505
8606
|
baseResult.price1hPcnt,
|
|
8506
8607
|
btc1h.length >= 2 ? percentChange(
|
|
@@ -8875,7 +8976,8 @@ var buildBaseContextSnapshot = ({
|
|
|
8875
8976
|
)
|
|
8876
8977
|
},
|
|
8877
8978
|
targetVsBtc,
|
|
8878
|
-
...targetVsEth != null ? { targetVsEth } : {}
|
|
8979
|
+
...targetVsEth != null ? { targetVsEth } : {},
|
|
8980
|
+
...referencePsychologicalLevels != null ? { referencePsychologicalLevels } : {}
|
|
8879
8981
|
}
|
|
8880
8982
|
};
|
|
8881
8983
|
let cachedMtfSnapshot = null;
|
|
@@ -10722,19 +10824,19 @@ var createIndicators = (data, btcData = [], options = {}) => {
|
|
|
10722
10824
|
volumeSeries: volumes,
|
|
10723
10825
|
btcCloseSeries: btcCloses,
|
|
10724
10826
|
coinResampledCandles: {
|
|
10725
|
-
h1: coin1hCache.snapshot(),
|
|
10726
|
-
h4: coin4hCache.snapshot(),
|
|
10727
|
-
d1: coin1dCache.snapshot()
|
|
10827
|
+
h1: coin1hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10828
|
+
h4: coin4hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10829
|
+
d1: coin1dCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW)
|
|
10728
10830
|
},
|
|
10729
10831
|
btcResampledCandles: {
|
|
10730
|
-
h1: btc1hCache.snapshot(),
|
|
10731
|
-
h4: btc4hCache.snapshot(),
|
|
10732
|
-
d1: btc1dCache.snapshot()
|
|
10832
|
+
h1: btc1hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10833
|
+
h4: btc4hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10834
|
+
d1: btc1dCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW)
|
|
10733
10835
|
},
|
|
10734
10836
|
ethResampledCandles: {
|
|
10735
|
-
h1: eth1hCache.snapshot(),
|
|
10736
|
-
h4: eth4hCache.snapshot(),
|
|
10737
|
-
d1: eth1dCache.snapshot()
|
|
10837
|
+
h1: eth1hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10838
|
+
h4: eth4hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10839
|
+
d1: eth1dCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW)
|
|
10738
10840
|
},
|
|
10739
10841
|
indicatorHistory,
|
|
10740
10842
|
indicatorPeriods,
|
package/dist/indicators.js
CHANGED
|
@@ -6984,6 +6984,12 @@ var SESSION_WINDOWS = [
|
|
|
6984
6984
|
var FUNDING_WINDOW_STEP_MINUTES = 8 * 60;
|
|
6985
6985
|
var FUNDING_WINDOW_NEARBY_MINUTES = 60;
|
|
6986
6986
|
var SESSION_WINDOW_EDGE_MINUTES = 60;
|
|
6987
|
+
var BASE_INTERVAL_MS = 15 * 6e4;
|
|
6988
|
+
var PSYCHOLOGICAL_LEVEL_WINDOWS = {
|
|
6989
|
+
m15: BASE_INTERVAL_MS,
|
|
6990
|
+
h1: 60 * 6e4,
|
|
6991
|
+
h4: 4 * 60 * 6e4
|
|
6992
|
+
};
|
|
6987
6993
|
var isInsideSession = (minuteUtc, startMinuteUtc, endMinuteUtc) => startMinuteUtc <= endMinuteUtc ? minuteUtc >= startMinuteUtc && minuteUtc < endMinuteUtc : minuteUtc >= startMinuteUtc || minuteUtc < endMinuteUtc;
|
|
6988
6994
|
var buildSessionContext = (timestamp) => {
|
|
6989
6995
|
const date = new Date(timestamp);
|
|
@@ -7015,7 +7021,80 @@ var buildSessionContext = (timestamp) => {
|
|
|
7015
7021
|
isWeekendUtc: dayOfWeekUtc >= 6
|
|
7016
7022
|
};
|
|
7017
7023
|
};
|
|
7024
|
+
var buildUnavailablePsychologicalLevelWindow = () => ({
|
|
7025
|
+
crossed: null,
|
|
7026
|
+
direction: "unknown",
|
|
7027
|
+
level: null,
|
|
7028
|
+
levelsCrossed: null,
|
|
7029
|
+
distanceBeyondLevelBps: null
|
|
7030
|
+
});
|
|
7031
|
+
var buildPsychologicalLevelWindow = (startPrice, endPrice, stepUsd) => {
|
|
7032
|
+
if (!Number.isFinite(startPrice) || !Number.isFinite(endPrice) || !Number.isFinite(stepUsd) || startPrice <= 0 || endPrice <= 0 || stepUsd <= 0) {
|
|
7033
|
+
return buildUnavailablePsychologicalLevelWindow();
|
|
7034
|
+
}
|
|
7035
|
+
if (endPrice === startPrice) {
|
|
7036
|
+
return {
|
|
7037
|
+
crossed: false,
|
|
7038
|
+
direction: "none",
|
|
7039
|
+
level: null,
|
|
7040
|
+
levelsCrossed: 0,
|
|
7041
|
+
distanceBeyondLevelBps: null
|
|
7042
|
+
};
|
|
7043
|
+
}
|
|
7044
|
+
const movingUp = endPrice > startPrice;
|
|
7045
|
+
const firstCrossedLevel = movingUp ? (Math.floor(startPrice / stepUsd) + 1) * stepUsd : (Math.ceil(startPrice / stepUsd) - 1) * stepUsd;
|
|
7046
|
+
const lastCrossedLevel = movingUp ? Math.floor(endPrice / stepUsd) * stepUsd : Math.ceil(endPrice / stepUsd) * stepUsd;
|
|
7047
|
+
const crossed = movingUp ? firstCrossedLevel <= lastCrossedLevel : firstCrossedLevel >= lastCrossedLevel;
|
|
7048
|
+
if (!crossed) {
|
|
7049
|
+
return {
|
|
7050
|
+
crossed: false,
|
|
7051
|
+
direction: "none",
|
|
7052
|
+
level: null,
|
|
7053
|
+
levelsCrossed: 0,
|
|
7054
|
+
distanceBeyondLevelBps: null
|
|
7055
|
+
};
|
|
7056
|
+
}
|
|
7057
|
+
const levelsCrossed = Math.round(Math.abs(lastCrossedLevel - firstCrossedLevel) / stepUsd) + 1;
|
|
7058
|
+
const distanceBeyondLevelBps = Math.abs(endPrice - lastCrossedLevel) / lastCrossedLevel * 1e4;
|
|
7059
|
+
return {
|
|
7060
|
+
crossed: true,
|
|
7061
|
+
direction: movingUp ? "up" : "down",
|
|
7062
|
+
level: lastCrossedLevel,
|
|
7063
|
+
levelsCrossed,
|
|
7064
|
+
distanceBeyondLevelBps
|
|
7065
|
+
};
|
|
7066
|
+
};
|
|
7067
|
+
var buildPsychologicalLevelAssetContext = (candles, stepUsd) => {
|
|
7068
|
+
const endCandle = candles[candles.length - 1];
|
|
7069
|
+
if (!endCandle) {
|
|
7070
|
+
return null;
|
|
7071
|
+
}
|
|
7072
|
+
const candlesByTimestamp = new Map(
|
|
7073
|
+
candles.map((item) => [item.timestamp, item])
|
|
7074
|
+
);
|
|
7075
|
+
const windows = Object.fromEntries(
|
|
7076
|
+
Object.entries(PSYCHOLOGICAL_LEVEL_WINDOWS).map(([window, durationMs]) => {
|
|
7077
|
+
const startCandle = candlesByTimestamp.get(
|
|
7078
|
+
endCandle.timestamp - durationMs
|
|
7079
|
+
);
|
|
7080
|
+
return [
|
|
7081
|
+
window,
|
|
7082
|
+
startCandle ? buildPsychologicalLevelWindow(
|
|
7083
|
+
startCandle.close,
|
|
7084
|
+
endCandle.close,
|
|
7085
|
+
stepUsd
|
|
7086
|
+
) : buildUnavailablePsychologicalLevelWindow()
|
|
7087
|
+
];
|
|
7088
|
+
})
|
|
7089
|
+
);
|
|
7090
|
+
return {
|
|
7091
|
+
source: "aligned_15m_ohlcv",
|
|
7092
|
+
stepUsd,
|
|
7093
|
+
windows
|
|
7094
|
+
};
|
|
7095
|
+
};
|
|
7018
7096
|
var STRUCTURE_LOOKBACK = 80;
|
|
7097
|
+
var BASE_CONTEXT_CANDLE_WINDOW = 256;
|
|
7019
7098
|
var PIVOT_LEFT_RIGHT = 2;
|
|
7020
7099
|
var ZONE_ATR_FACTOR = 0.5;
|
|
7021
7100
|
var PROFILE_BIN_COUNT = 24;
|
|
@@ -8439,12 +8518,12 @@ var buildBaseContextSnapshot = ({
|
|
|
8439
8518
|
candle,
|
|
8440
8519
|
prevCandle,
|
|
8441
8520
|
baseResult,
|
|
8442
|
-
candlesHistory,
|
|
8443
|
-
btcCandlesHistory,
|
|
8444
|
-
ethCandlesHistory = [],
|
|
8445
|
-
closeSeries,
|
|
8446
|
-
volumeSeries,
|
|
8447
|
-
btcCloseSeries,
|
|
8521
|
+
candlesHistory: fullCandlesHistory,
|
|
8522
|
+
btcCandlesHistory: fullBtcCandlesHistory,
|
|
8523
|
+
ethCandlesHistory: fullEthCandlesHistory = [],
|
|
8524
|
+
closeSeries: fullCloseSeries,
|
|
8525
|
+
volumeSeries: fullVolumeSeries,
|
|
8526
|
+
btcCloseSeries: fullBtcCloseSeries,
|
|
8448
8527
|
coinResampledCandles,
|
|
8449
8528
|
btcResampledCandles,
|
|
8450
8529
|
ethResampledCandles,
|
|
@@ -8459,6 +8538,16 @@ var buildBaseContextSnapshot = ({
|
|
|
8459
8538
|
adaptiveChannel: precomputedAdaptiveChannel,
|
|
8460
8539
|
psar: precomputedPsar
|
|
8461
8540
|
}) => {
|
|
8541
|
+
const candlesHistory = fullCandlesHistory.slice(-BASE_CONTEXT_CANDLE_WINDOW);
|
|
8542
|
+
const btcCandlesHistory = fullBtcCandlesHistory.slice(
|
|
8543
|
+
-BASE_CONTEXT_CANDLE_WINDOW
|
|
8544
|
+
);
|
|
8545
|
+
const ethCandlesHistory = fullEthCandlesHistory.slice(
|
|
8546
|
+
-BASE_CONTEXT_CANDLE_WINDOW
|
|
8547
|
+
);
|
|
8548
|
+
const closeSeries = fullCloseSeries.slice(-BASE_CONTEXT_CANDLE_WINDOW);
|
|
8549
|
+
const volumeSeries = fullVolumeSeries.slice(-BASE_CONTEXT_CANDLE_WINDOW);
|
|
8550
|
+
const btcCloseSeries = fullBtcCloseSeries.slice(-BASE_CONTEXT_CANDLE_WINDOW);
|
|
8462
8551
|
const atr2 = toNullable(baseResult.atr);
|
|
8463
8552
|
const bbWidthPct = baseResult.bbUpper != null && baseResult.bbLower != null && baseResult.bbMiddle != null && baseResult.bbMiddle !== 0 ? (baseResult.bbUpper - baseResult.bbLower) / baseResult.bbMiddle * 100 : null;
|
|
8464
8553
|
const atrPctSeries = materializeNumericHistory(
|
|
@@ -8616,6 +8705,18 @@ var buildBaseContextSnapshot = ({
|
|
|
8616
8705
|
coinCandles: candlesHistory,
|
|
8617
8706
|
ethCandles: ethCandlesHistory
|
|
8618
8707
|
}) : null;
|
|
8708
|
+
const btcPsychologicalLevels = buildPsychologicalLevelAssetContext(
|
|
8709
|
+
btcCandlesHistory,
|
|
8710
|
+
1e3
|
|
8711
|
+
);
|
|
8712
|
+
const ethPsychologicalLevels = buildPsychologicalLevelAssetContext(
|
|
8713
|
+
ethCandlesHistory,
|
|
8714
|
+
100
|
|
8715
|
+
);
|
|
8716
|
+
const referencePsychologicalLevels = btcPsychologicalLevels != null || ethPsychologicalLevels != null ? {
|
|
8717
|
+
...btcPsychologicalLevels != null ? { BTCUSDT: btcPsychologicalLevels } : {},
|
|
8718
|
+
...ethPsychologicalLevels != null ? { ETHUSDT: ethPsychologicalLevels } : {}
|
|
8719
|
+
} : null;
|
|
8619
8720
|
const relativeStrength1h = getRelativeChange(
|
|
8620
8721
|
baseResult.price1hPcnt,
|
|
8621
8722
|
btc1h.length >= 2 ? percentChange(
|
|
@@ -8990,7 +9091,8 @@ var buildBaseContextSnapshot = ({
|
|
|
8990
9091
|
)
|
|
8991
9092
|
},
|
|
8992
9093
|
targetVsBtc,
|
|
8993
|
-
...targetVsEth != null ? { targetVsEth } : {}
|
|
9094
|
+
...targetVsEth != null ? { targetVsEth } : {},
|
|
9095
|
+
...referencePsychologicalLevels != null ? { referencePsychologicalLevels } : {}
|
|
8994
9096
|
}
|
|
8995
9097
|
};
|
|
8996
9098
|
let cachedMtfSnapshot = null;
|
|
@@ -10837,19 +10939,19 @@ var createIndicators = (data, btcData = [], options = {}) => {
|
|
|
10837
10939
|
volumeSeries: volumes,
|
|
10838
10940
|
btcCloseSeries: btcCloses,
|
|
10839
10941
|
coinResampledCandles: {
|
|
10840
|
-
h1: coin1hCache.snapshot(),
|
|
10841
|
-
h4: coin4hCache.snapshot(),
|
|
10842
|
-
d1: coin1dCache.snapshot()
|
|
10942
|
+
h1: coin1hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10943
|
+
h4: coin4hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10944
|
+
d1: coin1dCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW)
|
|
10843
10945
|
},
|
|
10844
10946
|
btcResampledCandles: {
|
|
10845
|
-
h1: btc1hCache.snapshot(),
|
|
10846
|
-
h4: btc4hCache.snapshot(),
|
|
10847
|
-
d1: btc1dCache.snapshot()
|
|
10947
|
+
h1: btc1hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10948
|
+
h4: btc4hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10949
|
+
d1: btc1dCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW)
|
|
10848
10950
|
},
|
|
10849
10951
|
ethResampledCandles: {
|
|
10850
|
-
h1: eth1hCache.snapshot(),
|
|
10851
|
-
h4: eth4hCache.snapshot(),
|
|
10852
|
-
d1: eth1dCache.snapshot()
|
|
10952
|
+
h1: eth1hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10953
|
+
h4: eth4hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10954
|
+
d1: eth1dCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW)
|
|
10853
10955
|
},
|
|
10854
10956
|
indicatorHistory,
|
|
10855
10957
|
indicatorPeriods,
|
package/dist/indicators.mjs
CHANGED
package/dist/strategies.d.mts
CHANGED
|
@@ -104,8 +104,14 @@ interface CreateStrategyAPIParams {
|
|
|
104
104
|
isConfigFromBacktest?: Signal['isConfigFromBacktest'];
|
|
105
105
|
sharedReplayKey?: string;
|
|
106
106
|
getSharedReplayState?: StrategySharedReplayStateGetter;
|
|
107
|
+
loadDecisionBaseContext?: (params: {
|
|
108
|
+
baseContext: BaseStrategyContextSnapshot | undefined;
|
|
109
|
+
candle: KlineChartData[number];
|
|
110
|
+
symbol: Signal['symbol'];
|
|
111
|
+
interval: Signal['interval'];
|
|
112
|
+
}) => Promise<BaseStrategyContextSnapshot | undefined>;
|
|
107
113
|
}
|
|
108
|
-
declare const createStrategyAPI: <TIndicators = IndicatorsHistorySnapshot | Record<string, unknown>>({ strategy, symbol, interval, env, connector, cachedData, indicatorsState, isConfigFromBacktest, sharedReplayKey, getSharedReplayState, }: CreateStrategyAPIParams) => StrategyAPI<TIndicators>;
|
|
114
|
+
declare const createStrategyAPI: <TIndicators = IndicatorsHistorySnapshot | Record<string, unknown>>({ strategy, symbol, interval, env, connector, cachedData, indicatorsState, isConfigFromBacktest, sharedReplayKey, getSharedReplayState, loadDecisionBaseContext, }: CreateStrategyAPIParams) => StrategyAPI<TIndicators>;
|
|
109
115
|
|
|
110
116
|
declare const getSharedStrategyReplayState: <TState>(key: string | undefined, createState: () => TState) => TState;
|
|
111
117
|
declare const releaseStrategyReplayCache: (keyPrefix: string) => void;
|
package/dist/strategies.d.ts
CHANGED
|
@@ -104,8 +104,14 @@ interface CreateStrategyAPIParams {
|
|
|
104
104
|
isConfigFromBacktest?: Signal['isConfigFromBacktest'];
|
|
105
105
|
sharedReplayKey?: string;
|
|
106
106
|
getSharedReplayState?: StrategySharedReplayStateGetter;
|
|
107
|
+
loadDecisionBaseContext?: (params: {
|
|
108
|
+
baseContext: BaseStrategyContextSnapshot | undefined;
|
|
109
|
+
candle: KlineChartData[number];
|
|
110
|
+
symbol: Signal['symbol'];
|
|
111
|
+
interval: Signal['interval'];
|
|
112
|
+
}) => Promise<BaseStrategyContextSnapshot | undefined>;
|
|
107
113
|
}
|
|
108
|
-
declare const createStrategyAPI: <TIndicators = IndicatorsHistorySnapshot | Record<string, unknown>>({ strategy, symbol, interval, env, connector, cachedData, indicatorsState, isConfigFromBacktest, sharedReplayKey, getSharedReplayState, }: CreateStrategyAPIParams) => StrategyAPI<TIndicators>;
|
|
114
|
+
declare const createStrategyAPI: <TIndicators = IndicatorsHistorySnapshot | Record<string, unknown>>({ strategy, symbol, interval, env, connector, cachedData, indicatorsState, isConfigFromBacktest, sharedReplayKey, getSharedReplayState, loadDecisionBaseContext, }: CreateStrategyAPIParams) => StrategyAPI<TIndicators>;
|
|
109
115
|
|
|
110
116
|
declare const getSharedStrategyReplayState: <TState>(key: string | undefined, createState: () => TState) => TState;
|
|
111
117
|
declare const releaseStrategyReplayCache: (keyPrefix: string) => void;
|
package/dist/strategies.js
CHANGED
|
@@ -6416,6 +6416,12 @@ var SESSION_WINDOWS = [
|
|
|
6416
6416
|
var FUNDING_WINDOW_STEP_MINUTES = 8 * 60;
|
|
6417
6417
|
var FUNDING_WINDOW_NEARBY_MINUTES = 60;
|
|
6418
6418
|
var SESSION_WINDOW_EDGE_MINUTES = 60;
|
|
6419
|
+
var BASE_INTERVAL_MS = 15 * 6e4;
|
|
6420
|
+
var PSYCHOLOGICAL_LEVEL_WINDOWS = {
|
|
6421
|
+
m15: BASE_INTERVAL_MS,
|
|
6422
|
+
h1: 60 * 6e4,
|
|
6423
|
+
h4: 4 * 60 * 6e4
|
|
6424
|
+
};
|
|
6419
6425
|
var isInsideSession = (minuteUtc, startMinuteUtc, endMinuteUtc) => startMinuteUtc <= endMinuteUtc ? minuteUtc >= startMinuteUtc && minuteUtc < endMinuteUtc : minuteUtc >= startMinuteUtc || minuteUtc < endMinuteUtc;
|
|
6420
6426
|
var buildSessionContext = (timestamp) => {
|
|
6421
6427
|
const date = new Date(timestamp);
|
|
@@ -6447,7 +6453,80 @@ var buildSessionContext = (timestamp) => {
|
|
|
6447
6453
|
isWeekendUtc: dayOfWeekUtc >= 6
|
|
6448
6454
|
};
|
|
6449
6455
|
};
|
|
6456
|
+
var buildUnavailablePsychologicalLevelWindow = () => ({
|
|
6457
|
+
crossed: null,
|
|
6458
|
+
direction: "unknown",
|
|
6459
|
+
level: null,
|
|
6460
|
+
levelsCrossed: null,
|
|
6461
|
+
distanceBeyondLevelBps: null
|
|
6462
|
+
});
|
|
6463
|
+
var buildPsychologicalLevelWindow = (startPrice, endPrice, stepUsd) => {
|
|
6464
|
+
if (!Number.isFinite(startPrice) || !Number.isFinite(endPrice) || !Number.isFinite(stepUsd) || startPrice <= 0 || endPrice <= 0 || stepUsd <= 0) {
|
|
6465
|
+
return buildUnavailablePsychologicalLevelWindow();
|
|
6466
|
+
}
|
|
6467
|
+
if (endPrice === startPrice) {
|
|
6468
|
+
return {
|
|
6469
|
+
crossed: false,
|
|
6470
|
+
direction: "none",
|
|
6471
|
+
level: null,
|
|
6472
|
+
levelsCrossed: 0,
|
|
6473
|
+
distanceBeyondLevelBps: null
|
|
6474
|
+
};
|
|
6475
|
+
}
|
|
6476
|
+
const movingUp = endPrice > startPrice;
|
|
6477
|
+
const firstCrossedLevel = movingUp ? (Math.floor(startPrice / stepUsd) + 1) * stepUsd : (Math.ceil(startPrice / stepUsd) - 1) * stepUsd;
|
|
6478
|
+
const lastCrossedLevel = movingUp ? Math.floor(endPrice / stepUsd) * stepUsd : Math.ceil(endPrice / stepUsd) * stepUsd;
|
|
6479
|
+
const crossed = movingUp ? firstCrossedLevel <= lastCrossedLevel : firstCrossedLevel >= lastCrossedLevel;
|
|
6480
|
+
if (!crossed) {
|
|
6481
|
+
return {
|
|
6482
|
+
crossed: false,
|
|
6483
|
+
direction: "none",
|
|
6484
|
+
level: null,
|
|
6485
|
+
levelsCrossed: 0,
|
|
6486
|
+
distanceBeyondLevelBps: null
|
|
6487
|
+
};
|
|
6488
|
+
}
|
|
6489
|
+
const levelsCrossed = Math.round(Math.abs(lastCrossedLevel - firstCrossedLevel) / stepUsd) + 1;
|
|
6490
|
+
const distanceBeyondLevelBps = Math.abs(endPrice - lastCrossedLevel) / lastCrossedLevel * 1e4;
|
|
6491
|
+
return {
|
|
6492
|
+
crossed: true,
|
|
6493
|
+
direction: movingUp ? "up" : "down",
|
|
6494
|
+
level: lastCrossedLevel,
|
|
6495
|
+
levelsCrossed,
|
|
6496
|
+
distanceBeyondLevelBps
|
|
6497
|
+
};
|
|
6498
|
+
};
|
|
6499
|
+
var buildPsychologicalLevelAssetContext = (candles, stepUsd) => {
|
|
6500
|
+
const endCandle = candles[candles.length - 1];
|
|
6501
|
+
if (!endCandle) {
|
|
6502
|
+
return null;
|
|
6503
|
+
}
|
|
6504
|
+
const candlesByTimestamp = new Map(
|
|
6505
|
+
candles.map((item) => [item.timestamp, item])
|
|
6506
|
+
);
|
|
6507
|
+
const windows = Object.fromEntries(
|
|
6508
|
+
Object.entries(PSYCHOLOGICAL_LEVEL_WINDOWS).map(([window, durationMs]) => {
|
|
6509
|
+
const startCandle = candlesByTimestamp.get(
|
|
6510
|
+
endCandle.timestamp - durationMs
|
|
6511
|
+
);
|
|
6512
|
+
return [
|
|
6513
|
+
window,
|
|
6514
|
+
startCandle ? buildPsychologicalLevelWindow(
|
|
6515
|
+
startCandle.close,
|
|
6516
|
+
endCandle.close,
|
|
6517
|
+
stepUsd
|
|
6518
|
+
) : buildUnavailablePsychologicalLevelWindow()
|
|
6519
|
+
];
|
|
6520
|
+
})
|
|
6521
|
+
);
|
|
6522
|
+
return {
|
|
6523
|
+
source: "aligned_15m_ohlcv",
|
|
6524
|
+
stepUsd,
|
|
6525
|
+
windows
|
|
6526
|
+
};
|
|
6527
|
+
};
|
|
6450
6528
|
var STRUCTURE_LOOKBACK = 80;
|
|
6529
|
+
var BASE_CONTEXT_CANDLE_WINDOW = 256;
|
|
6451
6530
|
var PIVOT_LEFT_RIGHT = 2;
|
|
6452
6531
|
var ZONE_ATR_FACTOR = 0.5;
|
|
6453
6532
|
var PROFILE_BIN_COUNT = 24;
|
|
@@ -7871,12 +7950,12 @@ var buildBaseContextSnapshot = ({
|
|
|
7871
7950
|
candle,
|
|
7872
7951
|
prevCandle,
|
|
7873
7952
|
baseResult,
|
|
7874
|
-
candlesHistory,
|
|
7875
|
-
btcCandlesHistory,
|
|
7876
|
-
ethCandlesHistory = [],
|
|
7877
|
-
closeSeries,
|
|
7878
|
-
volumeSeries,
|
|
7879
|
-
btcCloseSeries,
|
|
7953
|
+
candlesHistory: fullCandlesHistory,
|
|
7954
|
+
btcCandlesHistory: fullBtcCandlesHistory,
|
|
7955
|
+
ethCandlesHistory: fullEthCandlesHistory = [],
|
|
7956
|
+
closeSeries: fullCloseSeries,
|
|
7957
|
+
volumeSeries: fullVolumeSeries,
|
|
7958
|
+
btcCloseSeries: fullBtcCloseSeries,
|
|
7880
7959
|
coinResampledCandles,
|
|
7881
7960
|
btcResampledCandles,
|
|
7882
7961
|
ethResampledCandles,
|
|
@@ -7891,6 +7970,16 @@ var buildBaseContextSnapshot = ({
|
|
|
7891
7970
|
adaptiveChannel: precomputedAdaptiveChannel,
|
|
7892
7971
|
psar: precomputedPsar
|
|
7893
7972
|
}) => {
|
|
7973
|
+
const candlesHistory = fullCandlesHistory.slice(-BASE_CONTEXT_CANDLE_WINDOW);
|
|
7974
|
+
const btcCandlesHistory = fullBtcCandlesHistory.slice(
|
|
7975
|
+
-BASE_CONTEXT_CANDLE_WINDOW
|
|
7976
|
+
);
|
|
7977
|
+
const ethCandlesHistory = fullEthCandlesHistory.slice(
|
|
7978
|
+
-BASE_CONTEXT_CANDLE_WINDOW
|
|
7979
|
+
);
|
|
7980
|
+
const closeSeries = fullCloseSeries.slice(-BASE_CONTEXT_CANDLE_WINDOW);
|
|
7981
|
+
const volumeSeries = fullVolumeSeries.slice(-BASE_CONTEXT_CANDLE_WINDOW);
|
|
7982
|
+
const btcCloseSeries = fullBtcCloseSeries.slice(-BASE_CONTEXT_CANDLE_WINDOW);
|
|
7894
7983
|
const atr2 = toNullable(baseResult.atr);
|
|
7895
7984
|
const bbWidthPct = baseResult.bbUpper != null && baseResult.bbLower != null && baseResult.bbMiddle != null && baseResult.bbMiddle !== 0 ? (baseResult.bbUpper - baseResult.bbLower) / baseResult.bbMiddle * 100 : null;
|
|
7896
7985
|
const atrPctSeries = materializeNumericHistory(
|
|
@@ -8048,6 +8137,18 @@ var buildBaseContextSnapshot = ({
|
|
|
8048
8137
|
coinCandles: candlesHistory,
|
|
8049
8138
|
ethCandles: ethCandlesHistory
|
|
8050
8139
|
}) : null;
|
|
8140
|
+
const btcPsychologicalLevels = buildPsychologicalLevelAssetContext(
|
|
8141
|
+
btcCandlesHistory,
|
|
8142
|
+
1e3
|
|
8143
|
+
);
|
|
8144
|
+
const ethPsychologicalLevels = buildPsychologicalLevelAssetContext(
|
|
8145
|
+
ethCandlesHistory,
|
|
8146
|
+
100
|
|
8147
|
+
);
|
|
8148
|
+
const referencePsychologicalLevels = btcPsychologicalLevels != null || ethPsychologicalLevels != null ? {
|
|
8149
|
+
...btcPsychologicalLevels != null ? { BTCUSDT: btcPsychologicalLevels } : {},
|
|
8150
|
+
...ethPsychologicalLevels != null ? { ETHUSDT: ethPsychologicalLevels } : {}
|
|
8151
|
+
} : null;
|
|
8051
8152
|
const relativeStrength1h = getRelativeChange(
|
|
8052
8153
|
baseResult.price1hPcnt,
|
|
8053
8154
|
btc1h.length >= 2 ? percentChange(
|
|
@@ -8422,7 +8523,8 @@ var buildBaseContextSnapshot = ({
|
|
|
8422
8523
|
)
|
|
8423
8524
|
},
|
|
8424
8525
|
targetVsBtc,
|
|
8425
|
-
...targetVsEth != null ? { targetVsEth } : {}
|
|
8526
|
+
...targetVsEth != null ? { targetVsEth } : {},
|
|
8527
|
+
...referencePsychologicalLevels != null ? { referencePsychologicalLevels } : {}
|
|
8426
8528
|
}
|
|
8427
8529
|
};
|
|
8428
8530
|
let cachedMtfSnapshot = null;
|
|
@@ -10136,19 +10238,19 @@ var createIndicators = (data, btcData = [], options = {}) => {
|
|
|
10136
10238
|
volumeSeries: volumes,
|
|
10137
10239
|
btcCloseSeries: btcCloses,
|
|
10138
10240
|
coinResampledCandles: {
|
|
10139
|
-
h1: coin1hCache.snapshot(),
|
|
10140
|
-
h4: coin4hCache.snapshot(),
|
|
10141
|
-
d1: coin1dCache.snapshot()
|
|
10241
|
+
h1: coin1hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10242
|
+
h4: coin4hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10243
|
+
d1: coin1dCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW)
|
|
10142
10244
|
},
|
|
10143
10245
|
btcResampledCandles: {
|
|
10144
|
-
h1: btc1hCache.snapshot(),
|
|
10145
|
-
h4: btc4hCache.snapshot(),
|
|
10146
|
-
d1: btc1dCache.snapshot()
|
|
10246
|
+
h1: btc1hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10247
|
+
h4: btc4hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10248
|
+
d1: btc1dCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW)
|
|
10147
10249
|
},
|
|
10148
10250
|
ethResampledCandles: {
|
|
10149
|
-
h1: eth1hCache.snapshot(),
|
|
10150
|
-
h4: eth4hCache.snapshot(),
|
|
10151
|
-
d1: eth1dCache.snapshot()
|
|
10251
|
+
h1: eth1hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10252
|
+
h4: eth4hCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW),
|
|
10253
|
+
d1: eth1dCache.snapshot().slice(-ML_BASE_CANDLES_WINDOW)
|
|
10152
10254
|
},
|
|
10153
10255
|
indicatorHistory,
|
|
10154
10256
|
indicatorPeriods,
|
|
@@ -10835,6 +10937,7 @@ var createStrategyIndicatorsState = ({
|
|
|
10835
10937
|
// Lazy bootstrap for live mode: initialize on history before current bar and then apply current bar once.
|
|
10836
10938
|
ensureInitializedWithCurrentBar: ensureControllerInitialized,
|
|
10837
10939
|
snapshot: (options) => ensureControllerInitialized().snapshot(options),
|
|
10940
|
+
latestSnapshot: () => ensureControllerInitialized().latestSnapshot(),
|
|
10838
10941
|
latestNumber: (key) => ensureControllerInitialized().latestNumber(key)
|
|
10839
10942
|
};
|
|
10840
10943
|
};
|
|
@@ -11236,6 +11339,7 @@ var pushWhen = (items, condition, item) => {
|
|
|
11236
11339
|
items.push(item);
|
|
11237
11340
|
}
|
|
11238
11341
|
};
|
|
11342
|
+
var HYPERLIQUID_WHALE_GATE_MIN_NOTIONAL_USD = 5e4;
|
|
11239
11343
|
var buildBaseContextGateFeatures = ({
|
|
11240
11344
|
baseContext,
|
|
11241
11345
|
direction,
|
|
@@ -11253,6 +11357,7 @@ var buildBaseContextGateFeatures = ({
|
|
|
11253
11357
|
const volume = baseContext.participation?.volume;
|
|
11254
11358
|
const delta = baseContext.participation?.delta;
|
|
11255
11359
|
const tradeFlow = baseContext.participation?.tradeFlow;
|
|
11360
|
+
const hyperliquidWhales = baseContext.participation?.hyperliquidWhales;
|
|
11256
11361
|
const volumeStructure = baseContext.participation?.volumeStructure;
|
|
11257
11362
|
const relative = baseContext.relative?.benchmark;
|
|
11258
11363
|
const marketBreadth = baseContext.relative?.marketBreadth;
|
|
@@ -11300,10 +11405,36 @@ var buildBaseContextGateFeatures = ({
|
|
|
11300
11405
|
const referenceTradeFlowBuyPressurePct = asFiniteNumberOrNull(
|
|
11301
11406
|
primaryReferenceTradeFlow?.buyPressurePct
|
|
11302
11407
|
);
|
|
11408
|
+
const rawHyperliquidWhaleBuySharePct = asFiniteNumberOrNull(
|
|
11409
|
+
hyperliquidWhales?.buySharePct
|
|
11410
|
+
);
|
|
11411
|
+
const rawHyperliquidWhaleNetNotionalUsd = asFiniteNumberOrNull(
|
|
11412
|
+
hyperliquidWhales?.netNotionalUsd
|
|
11413
|
+
);
|
|
11414
|
+
const rawHyperliquidWhaleUniqueCount = asFiniteNumberOrNull(
|
|
11415
|
+
hyperliquidWhales?.uniqueWhales
|
|
11416
|
+
);
|
|
11417
|
+
const hyperliquidWhaleCoveredCount = asFiniteNumberOrNull(
|
|
11418
|
+
hyperliquidWhales?.coveredWhales
|
|
11419
|
+
);
|
|
11420
|
+
const hyperliquidWhaleExpectedCount = asFiniteNumberOrNull(
|
|
11421
|
+
hyperliquidWhales?.expectedWhales
|
|
11422
|
+
);
|
|
11423
|
+
const hyperliquidWhaleCoveragePct = asFiniteNumberOrNull(
|
|
11424
|
+
hyperliquidWhales?.coveragePct
|
|
11425
|
+
);
|
|
11426
|
+
const hyperliquidWhaleCoverageSufficient = typeof hyperliquidWhales?.coverageSufficient === "boolean" ? hyperliquidWhales.coverageSufficient : null;
|
|
11427
|
+
const hyperliquidWhaleBuySharePct = hyperliquidWhaleCoverageSufficient === true ? rawHyperliquidWhaleBuySharePct : null;
|
|
11428
|
+
const hyperliquidWhaleNetNotionalUsd = hyperliquidWhaleCoverageSufficient === true ? rawHyperliquidWhaleNetNotionalUsd : null;
|
|
11429
|
+
const hyperliquidWhaleUniqueCount = hyperliquidWhaleCoverageSufficient === true ? rawHyperliquidWhaleUniqueCount : null;
|
|
11430
|
+
const hyperliquidWhaleNotionalUsd = hyperliquidWhaleCoverageSufficient === true ? (asFiniteNumberOrNull(hyperliquidWhales?.buyNotionalUsd) ?? 0) + (asFiniteNumberOrNull(hyperliquidWhales?.sellNotionalUsd) ?? 0) : null;
|
|
11431
|
+
const hyperliquidWhaleSufficientActivity = hyperliquidWhales == null || hyperliquidWhales.stale || hyperliquidWhaleCoverageSufficient !== true ? null : (hyperliquidWhaleNotionalUsd ?? 0) >= HYPERLIQUID_WHALE_GATE_MIN_NOTIONAL_USD;
|
|
11303
11432
|
const deltaDivergenceVsPrice = asStringOrNull(delta?.deltaDivergenceVsPrice);
|
|
11304
11433
|
const deltaBias = deltaDivergenceVsPrice === "bullish" || deltaDivergenceVsPrice === "bearish" ? deltaDivergenceVsPrice === "bullish" ? "bull" : "bear" : toPressureBias(buyPressurePct);
|
|
11305
11434
|
const tradeFlowBias = tradeFlow?.stale ? "unknown" : toPressureBias(tradeFlowBuyPressurePct);
|
|
11306
11435
|
const referenceTradeFlowBias = primaryReferenceTradeFlow?.stale ? "unknown" : toPressureBias(referenceTradeFlowBuyPressurePct);
|
|
11436
|
+
const hyperliquidWhaleFlowStale = typeof hyperliquidWhales?.stale === "boolean" ? hyperliquidWhales.stale : null;
|
|
11437
|
+
const hyperliquidWhaleFlowBias = hyperliquidWhaleSufficientActivity !== true ? "unknown" : toPressureBias(hyperliquidWhaleBuySharePct);
|
|
11307
11438
|
const deltaAligned = toBiasAligned({ direction, bias: deltaBias });
|
|
11308
11439
|
const tradeFlowAligned = toBiasAligned({
|
|
11309
11440
|
direction,
|
|
@@ -11313,6 +11444,10 @@ var buildBaseContextGateFeatures = ({
|
|
|
11313
11444
|
direction,
|
|
11314
11445
|
bias: referenceTradeFlowBias
|
|
11315
11446
|
});
|
|
11447
|
+
const hyperliquidWhaleFlowAligned = toBiasAligned({
|
|
11448
|
+
direction,
|
|
11449
|
+
bias: hyperliquidWhaleFlowBias
|
|
11450
|
+
});
|
|
11316
11451
|
const benchmarkTrendAlignment = relative?.trendAlignment ?? "unknown";
|
|
11317
11452
|
const relativeStrength1h = asFiniteNumberOrNull(relative?.relativeStrength1h);
|
|
11318
11453
|
const relativeStrengthBucket = toRelativeStrengthBucket({
|
|
@@ -11420,6 +11555,11 @@ var buildBaseContextGateFeatures = ({
|
|
|
11420
11555
|
pushWhen(confirmations, (volumeRel20 ?? 0) >= 1.5, "volume_expansion");
|
|
11421
11556
|
pushWhen(confirmations, deltaAligned === true, "delta_aligned");
|
|
11422
11557
|
pushWhen(confirmations, tradeFlowAligned === true, "trade_flow_aligned");
|
|
11558
|
+
pushWhen(
|
|
11559
|
+
confirmations,
|
|
11560
|
+
hyperliquidWhaleFlowAligned === true,
|
|
11561
|
+
"hyperliquid_whales_aligned"
|
|
11562
|
+
);
|
|
11423
11563
|
pushWhen(
|
|
11424
11564
|
confirmations,
|
|
11425
11565
|
referenceTradeFlowAligned === true,
|
|
@@ -11494,6 +11634,11 @@ var buildBaseContextGateFeatures = ({
|
|
|
11494
11634
|
pushWhen(conflicts, btcAltRegimeAligned === false, "btc_alt_regime_against");
|
|
11495
11635
|
pushWhen(conflicts, deltaAligned === false, "delta_against");
|
|
11496
11636
|
pushWhen(conflicts, tradeFlowAligned === false, "trade_flow_against");
|
|
11637
|
+
pushWhen(
|
|
11638
|
+
conflicts,
|
|
11639
|
+
hyperliquidWhaleFlowAligned === false,
|
|
11640
|
+
"hyperliquid_whales_against"
|
|
11641
|
+
);
|
|
11497
11642
|
pushWhen(
|
|
11498
11643
|
conflicts,
|
|
11499
11644
|
referenceTradeFlowAligned === false,
|
|
@@ -11519,6 +11664,7 @@ var buildBaseContextGateFeatures = ({
|
|
|
11519
11664
|
volumeRel20 == null ? null : volumeRel20 >= 1.5,
|
|
11520
11665
|
deltaAligned,
|
|
11521
11666
|
tradeFlowAligned,
|
|
11667
|
+
hyperliquidWhaleFlowAligned,
|
|
11522
11668
|
referenceTradeFlowAligned,
|
|
11523
11669
|
volumeStructureAligned
|
|
11524
11670
|
]),
|
|
@@ -11624,6 +11770,17 @@ var buildBaseContextGateFeatures = ({
|
|
|
11624
11770
|
deltaAligned,
|
|
11625
11771
|
tradeFlowBuyPressurePct,
|
|
11626
11772
|
tradeFlowAligned,
|
|
11773
|
+
hyperliquidWhaleBuySharePct,
|
|
11774
|
+
hyperliquidWhaleNetNotionalUsd,
|
|
11775
|
+
hyperliquidWhaleUniqueCount,
|
|
11776
|
+
hyperliquidWhaleCoveredCount,
|
|
11777
|
+
hyperliquidWhaleExpectedCount,
|
|
11778
|
+
hyperliquidWhaleCoveragePct,
|
|
11779
|
+
hyperliquidWhaleCoverageSufficient,
|
|
11780
|
+
hyperliquidWhaleNotionalUsd,
|
|
11781
|
+
hyperliquidWhaleSufficientActivity,
|
|
11782
|
+
hyperliquidWhaleFlowAligned,
|
|
11783
|
+
hyperliquidWhaleFlowStale,
|
|
11627
11784
|
referenceTradeFlowBuyPressurePct,
|
|
11628
11785
|
referenceTradeFlowAligned,
|
|
11629
11786
|
volumeStructureAligned
|
|
@@ -11836,7 +11993,8 @@ var createStrategyAPI = ({
|
|
|
11836
11993
|
indicatorsState,
|
|
11837
11994
|
isConfigFromBacktest,
|
|
11838
11995
|
sharedReplayKey,
|
|
11839
|
-
getSharedReplayState
|
|
11996
|
+
getSharedReplayState,
|
|
11997
|
+
loadDecisionBaseContext
|
|
11840
11998
|
}) => {
|
|
11841
11999
|
const isBacktestEnv = env === "BACKTEST";
|
|
11842
12000
|
const barCache = {
|
|
@@ -11844,6 +12002,7 @@ var createStrategyAPI = ({
|
|
|
11844
12002
|
currentPosition: void 0
|
|
11845
12003
|
};
|
|
11846
12004
|
let currentIndicatorsContextCache;
|
|
12005
|
+
let decisionBaseContextCache;
|
|
11847
12006
|
const getCurrentBarTimestamp = () => {
|
|
11848
12007
|
const lastCandle = cachedData[cachedData.length - 1];
|
|
11849
12008
|
return typeof lastCandle?.timestamp === "number" ? lastCandle.timestamp : null;
|
|
@@ -11875,6 +12034,7 @@ var createStrategyAPI = ({
|
|
|
11875
12034
|
barCache.timestamp = currentBarTimestamp;
|
|
11876
12035
|
barCache.currentPosition = void 0;
|
|
11877
12036
|
currentIndicatorsContextCache = void 0;
|
|
12037
|
+
decisionBaseContextCache = void 0;
|
|
11878
12038
|
};
|
|
11879
12039
|
const getCurrentPosition = () => {
|
|
11880
12040
|
if (!isBacktestEnv) {
|
|
@@ -11911,7 +12071,44 @@ var createStrategyAPI = ({
|
|
|
11911
12071
|
};
|
|
11912
12072
|
return context;
|
|
11913
12073
|
};
|
|
11914
|
-
const getBaseContext = () =>
|
|
12074
|
+
const getBaseContext = () => {
|
|
12075
|
+
ensureBarCache();
|
|
12076
|
+
const cacheKey = getCurrentIndicatorsCacheKey();
|
|
12077
|
+
if (currentIndicatorsContextCache?.key === cacheKey) {
|
|
12078
|
+
return currentIndicatorsContextCache.context.baseContext;
|
|
12079
|
+
}
|
|
12080
|
+
if (!indicatorsState?.latestSnapshot) {
|
|
12081
|
+
return getCurrentIndicatorsContext().baseContext;
|
|
12082
|
+
}
|
|
12083
|
+
indicatorsState?.onBar();
|
|
12084
|
+
const latestBaseContext = getBaseContextFromIndicators(
|
|
12085
|
+
indicatorsState.latestSnapshot()
|
|
12086
|
+
);
|
|
12087
|
+
return latestBaseContext ?? getCurrentIndicatorsContext().baseContext;
|
|
12088
|
+
};
|
|
12089
|
+
const getDecisionBaseContext = () => {
|
|
12090
|
+
ensureBarCache();
|
|
12091
|
+
const baseContext = getBaseContext();
|
|
12092
|
+
if (!loadDecisionBaseContext) {
|
|
12093
|
+
return Promise.resolve(baseContext);
|
|
12094
|
+
}
|
|
12095
|
+
const candle = cachedData[cachedData.length - 1];
|
|
12096
|
+
if (!candle) {
|
|
12097
|
+
return Promise.resolve(baseContext);
|
|
12098
|
+
}
|
|
12099
|
+
const cacheKey = getCurrentIndicatorsCacheKey();
|
|
12100
|
+
if (decisionBaseContextCache?.key === cacheKey) {
|
|
12101
|
+
return decisionBaseContextCache.context;
|
|
12102
|
+
}
|
|
12103
|
+
const context = loadDecisionBaseContext({
|
|
12104
|
+
baseContext,
|
|
12105
|
+
candle,
|
|
12106
|
+
symbol,
|
|
12107
|
+
interval
|
|
12108
|
+
});
|
|
12109
|
+
decisionBaseContextCache = { key: cacheKey, context };
|
|
12110
|
+
return context;
|
|
12111
|
+
};
|
|
11915
12112
|
const resolveDecisionPriceContext = () => {
|
|
11916
12113
|
const candle = cachedData[cachedData.length - 1];
|
|
11917
12114
|
if (!candle || !isFiniteNumber3(candle.timestamp) || !isFiniteNumber3(candle.close)) {
|
|
@@ -12001,6 +12198,7 @@ var createStrategyAPI = ({
|
|
|
12001
12198
|
}),
|
|
12002
12199
|
getCurrentIndicatorsContext,
|
|
12003
12200
|
getBaseContext,
|
|
12201
|
+
getDecisionBaseContext,
|
|
12004
12202
|
getDecisionPriceContext,
|
|
12005
12203
|
getCurrentPosition,
|
|
12006
12204
|
getDirectionalTpSlPrices: (params) => getDirectionalTpSlPrices(params),
|
package/dist/strategies.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createIndicators,
|
|
3
3
|
getRequiredControllerSeedWindow
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-HVCNGDPT.mjs";
|
|
5
5
|
import "./chunk-AYC2QVKI.mjs";
|
|
6
6
|
import "./chunk-M7QGVZ3J.mjs";
|
|
7
7
|
import {
|
|
@@ -297,6 +297,7 @@ var createStrategyIndicatorsState = ({
|
|
|
297
297
|
// Lazy bootstrap for live mode: initialize on history before current bar and then apply current bar once.
|
|
298
298
|
ensureInitializedWithCurrentBar: ensureControllerInitialized,
|
|
299
299
|
snapshot: (options) => ensureControllerInitialized().snapshot(options),
|
|
300
|
+
latestSnapshot: () => ensureControllerInitialized().latestSnapshot(),
|
|
300
301
|
latestNumber: (key) => ensureControllerInitialized().latestNumber(key)
|
|
301
302
|
};
|
|
302
303
|
};
|
|
@@ -691,6 +692,7 @@ var pushWhen = (items, condition, item) => {
|
|
|
691
692
|
items.push(item);
|
|
692
693
|
}
|
|
693
694
|
};
|
|
695
|
+
var HYPERLIQUID_WHALE_GATE_MIN_NOTIONAL_USD = 5e4;
|
|
694
696
|
var buildBaseContextGateFeatures = ({
|
|
695
697
|
baseContext,
|
|
696
698
|
direction,
|
|
@@ -708,6 +710,7 @@ var buildBaseContextGateFeatures = ({
|
|
|
708
710
|
const volume = baseContext.participation?.volume;
|
|
709
711
|
const delta = baseContext.participation?.delta;
|
|
710
712
|
const tradeFlow = baseContext.participation?.tradeFlow;
|
|
713
|
+
const hyperliquidWhales = baseContext.participation?.hyperliquidWhales;
|
|
711
714
|
const volumeStructure = baseContext.participation?.volumeStructure;
|
|
712
715
|
const relative = baseContext.relative?.benchmark;
|
|
713
716
|
const marketBreadth = baseContext.relative?.marketBreadth;
|
|
@@ -755,10 +758,36 @@ var buildBaseContextGateFeatures = ({
|
|
|
755
758
|
const referenceTradeFlowBuyPressurePct = asFiniteNumberOrNull(
|
|
756
759
|
primaryReferenceTradeFlow?.buyPressurePct
|
|
757
760
|
);
|
|
761
|
+
const rawHyperliquidWhaleBuySharePct = asFiniteNumberOrNull(
|
|
762
|
+
hyperliquidWhales?.buySharePct
|
|
763
|
+
);
|
|
764
|
+
const rawHyperliquidWhaleNetNotionalUsd = asFiniteNumberOrNull(
|
|
765
|
+
hyperliquidWhales?.netNotionalUsd
|
|
766
|
+
);
|
|
767
|
+
const rawHyperliquidWhaleUniqueCount = asFiniteNumberOrNull(
|
|
768
|
+
hyperliquidWhales?.uniqueWhales
|
|
769
|
+
);
|
|
770
|
+
const hyperliquidWhaleCoveredCount = asFiniteNumberOrNull(
|
|
771
|
+
hyperliquidWhales?.coveredWhales
|
|
772
|
+
);
|
|
773
|
+
const hyperliquidWhaleExpectedCount = asFiniteNumberOrNull(
|
|
774
|
+
hyperliquidWhales?.expectedWhales
|
|
775
|
+
);
|
|
776
|
+
const hyperliquidWhaleCoveragePct = asFiniteNumberOrNull(
|
|
777
|
+
hyperliquidWhales?.coveragePct
|
|
778
|
+
);
|
|
779
|
+
const hyperliquidWhaleCoverageSufficient = typeof hyperliquidWhales?.coverageSufficient === "boolean" ? hyperliquidWhales.coverageSufficient : null;
|
|
780
|
+
const hyperliquidWhaleBuySharePct = hyperliquidWhaleCoverageSufficient === true ? rawHyperliquidWhaleBuySharePct : null;
|
|
781
|
+
const hyperliquidWhaleNetNotionalUsd = hyperliquidWhaleCoverageSufficient === true ? rawHyperliquidWhaleNetNotionalUsd : null;
|
|
782
|
+
const hyperliquidWhaleUniqueCount = hyperliquidWhaleCoverageSufficient === true ? rawHyperliquidWhaleUniqueCount : null;
|
|
783
|
+
const hyperliquidWhaleNotionalUsd = hyperliquidWhaleCoverageSufficient === true ? (asFiniteNumberOrNull(hyperliquidWhales?.buyNotionalUsd) ?? 0) + (asFiniteNumberOrNull(hyperliquidWhales?.sellNotionalUsd) ?? 0) : null;
|
|
784
|
+
const hyperliquidWhaleSufficientActivity = hyperliquidWhales == null || hyperliquidWhales.stale || hyperliquidWhaleCoverageSufficient !== true ? null : (hyperliquidWhaleNotionalUsd ?? 0) >= HYPERLIQUID_WHALE_GATE_MIN_NOTIONAL_USD;
|
|
758
785
|
const deltaDivergenceVsPrice = asStringOrNull(delta?.deltaDivergenceVsPrice);
|
|
759
786
|
const deltaBias = deltaDivergenceVsPrice === "bullish" || deltaDivergenceVsPrice === "bearish" ? deltaDivergenceVsPrice === "bullish" ? "bull" : "bear" : toPressureBias(buyPressurePct);
|
|
760
787
|
const tradeFlowBias = tradeFlow?.stale ? "unknown" : toPressureBias(tradeFlowBuyPressurePct);
|
|
761
788
|
const referenceTradeFlowBias = primaryReferenceTradeFlow?.stale ? "unknown" : toPressureBias(referenceTradeFlowBuyPressurePct);
|
|
789
|
+
const hyperliquidWhaleFlowStale = typeof hyperliquidWhales?.stale === "boolean" ? hyperliquidWhales.stale : null;
|
|
790
|
+
const hyperliquidWhaleFlowBias = hyperliquidWhaleSufficientActivity !== true ? "unknown" : toPressureBias(hyperliquidWhaleBuySharePct);
|
|
762
791
|
const deltaAligned = toBiasAligned({ direction, bias: deltaBias });
|
|
763
792
|
const tradeFlowAligned = toBiasAligned({
|
|
764
793
|
direction,
|
|
@@ -768,6 +797,10 @@ var buildBaseContextGateFeatures = ({
|
|
|
768
797
|
direction,
|
|
769
798
|
bias: referenceTradeFlowBias
|
|
770
799
|
});
|
|
800
|
+
const hyperliquidWhaleFlowAligned = toBiasAligned({
|
|
801
|
+
direction,
|
|
802
|
+
bias: hyperliquidWhaleFlowBias
|
|
803
|
+
});
|
|
771
804
|
const benchmarkTrendAlignment = relative?.trendAlignment ?? "unknown";
|
|
772
805
|
const relativeStrength1h = asFiniteNumberOrNull(relative?.relativeStrength1h);
|
|
773
806
|
const relativeStrengthBucket = toRelativeStrengthBucket({
|
|
@@ -875,6 +908,11 @@ var buildBaseContextGateFeatures = ({
|
|
|
875
908
|
pushWhen(confirmations, (volumeRel20 ?? 0) >= 1.5, "volume_expansion");
|
|
876
909
|
pushWhen(confirmations, deltaAligned === true, "delta_aligned");
|
|
877
910
|
pushWhen(confirmations, tradeFlowAligned === true, "trade_flow_aligned");
|
|
911
|
+
pushWhen(
|
|
912
|
+
confirmations,
|
|
913
|
+
hyperliquidWhaleFlowAligned === true,
|
|
914
|
+
"hyperliquid_whales_aligned"
|
|
915
|
+
);
|
|
878
916
|
pushWhen(
|
|
879
917
|
confirmations,
|
|
880
918
|
referenceTradeFlowAligned === true,
|
|
@@ -949,6 +987,11 @@ var buildBaseContextGateFeatures = ({
|
|
|
949
987
|
pushWhen(conflicts, btcAltRegimeAligned === false, "btc_alt_regime_against");
|
|
950
988
|
pushWhen(conflicts, deltaAligned === false, "delta_against");
|
|
951
989
|
pushWhen(conflicts, tradeFlowAligned === false, "trade_flow_against");
|
|
990
|
+
pushWhen(
|
|
991
|
+
conflicts,
|
|
992
|
+
hyperliquidWhaleFlowAligned === false,
|
|
993
|
+
"hyperliquid_whales_against"
|
|
994
|
+
);
|
|
952
995
|
pushWhen(
|
|
953
996
|
conflicts,
|
|
954
997
|
referenceTradeFlowAligned === false,
|
|
@@ -974,6 +1017,7 @@ var buildBaseContextGateFeatures = ({
|
|
|
974
1017
|
volumeRel20 == null ? null : volumeRel20 >= 1.5,
|
|
975
1018
|
deltaAligned,
|
|
976
1019
|
tradeFlowAligned,
|
|
1020
|
+
hyperliquidWhaleFlowAligned,
|
|
977
1021
|
referenceTradeFlowAligned,
|
|
978
1022
|
volumeStructureAligned
|
|
979
1023
|
]),
|
|
@@ -1079,6 +1123,17 @@ var buildBaseContextGateFeatures = ({
|
|
|
1079
1123
|
deltaAligned,
|
|
1080
1124
|
tradeFlowBuyPressurePct,
|
|
1081
1125
|
tradeFlowAligned,
|
|
1126
|
+
hyperliquidWhaleBuySharePct,
|
|
1127
|
+
hyperliquidWhaleNetNotionalUsd,
|
|
1128
|
+
hyperliquidWhaleUniqueCount,
|
|
1129
|
+
hyperliquidWhaleCoveredCount,
|
|
1130
|
+
hyperliquidWhaleExpectedCount,
|
|
1131
|
+
hyperliquidWhaleCoveragePct,
|
|
1132
|
+
hyperliquidWhaleCoverageSufficient,
|
|
1133
|
+
hyperliquidWhaleNotionalUsd,
|
|
1134
|
+
hyperliquidWhaleSufficientActivity,
|
|
1135
|
+
hyperliquidWhaleFlowAligned,
|
|
1136
|
+
hyperliquidWhaleFlowStale,
|
|
1082
1137
|
referenceTradeFlowBuyPressurePct,
|
|
1083
1138
|
referenceTradeFlowAligned,
|
|
1084
1139
|
volumeStructureAligned
|
|
@@ -1291,7 +1346,8 @@ var createStrategyAPI = ({
|
|
|
1291
1346
|
indicatorsState,
|
|
1292
1347
|
isConfigFromBacktest,
|
|
1293
1348
|
sharedReplayKey,
|
|
1294
|
-
getSharedReplayState
|
|
1349
|
+
getSharedReplayState,
|
|
1350
|
+
loadDecisionBaseContext
|
|
1295
1351
|
}) => {
|
|
1296
1352
|
const isBacktestEnv = env === "BACKTEST";
|
|
1297
1353
|
const barCache = {
|
|
@@ -1299,6 +1355,7 @@ var createStrategyAPI = ({
|
|
|
1299
1355
|
currentPosition: void 0
|
|
1300
1356
|
};
|
|
1301
1357
|
let currentIndicatorsContextCache;
|
|
1358
|
+
let decisionBaseContextCache;
|
|
1302
1359
|
const getCurrentBarTimestamp = () => {
|
|
1303
1360
|
const lastCandle = cachedData[cachedData.length - 1];
|
|
1304
1361
|
return typeof lastCandle?.timestamp === "number" ? lastCandle.timestamp : null;
|
|
@@ -1330,6 +1387,7 @@ var createStrategyAPI = ({
|
|
|
1330
1387
|
barCache.timestamp = currentBarTimestamp;
|
|
1331
1388
|
barCache.currentPosition = void 0;
|
|
1332
1389
|
currentIndicatorsContextCache = void 0;
|
|
1390
|
+
decisionBaseContextCache = void 0;
|
|
1333
1391
|
};
|
|
1334
1392
|
const getCurrentPosition = () => {
|
|
1335
1393
|
if (!isBacktestEnv) {
|
|
@@ -1366,7 +1424,44 @@ var createStrategyAPI = ({
|
|
|
1366
1424
|
};
|
|
1367
1425
|
return context;
|
|
1368
1426
|
};
|
|
1369
|
-
const getBaseContext = () =>
|
|
1427
|
+
const getBaseContext = () => {
|
|
1428
|
+
ensureBarCache();
|
|
1429
|
+
const cacheKey = getCurrentIndicatorsCacheKey();
|
|
1430
|
+
if (currentIndicatorsContextCache?.key === cacheKey) {
|
|
1431
|
+
return currentIndicatorsContextCache.context.baseContext;
|
|
1432
|
+
}
|
|
1433
|
+
if (!indicatorsState?.latestSnapshot) {
|
|
1434
|
+
return getCurrentIndicatorsContext().baseContext;
|
|
1435
|
+
}
|
|
1436
|
+
indicatorsState?.onBar();
|
|
1437
|
+
const latestBaseContext = getBaseContextFromIndicators(
|
|
1438
|
+
indicatorsState.latestSnapshot()
|
|
1439
|
+
);
|
|
1440
|
+
return latestBaseContext ?? getCurrentIndicatorsContext().baseContext;
|
|
1441
|
+
};
|
|
1442
|
+
const getDecisionBaseContext = () => {
|
|
1443
|
+
ensureBarCache();
|
|
1444
|
+
const baseContext = getBaseContext();
|
|
1445
|
+
if (!loadDecisionBaseContext) {
|
|
1446
|
+
return Promise.resolve(baseContext);
|
|
1447
|
+
}
|
|
1448
|
+
const candle = cachedData[cachedData.length - 1];
|
|
1449
|
+
if (!candle) {
|
|
1450
|
+
return Promise.resolve(baseContext);
|
|
1451
|
+
}
|
|
1452
|
+
const cacheKey = getCurrentIndicatorsCacheKey();
|
|
1453
|
+
if (decisionBaseContextCache?.key === cacheKey) {
|
|
1454
|
+
return decisionBaseContextCache.context;
|
|
1455
|
+
}
|
|
1456
|
+
const context = loadDecisionBaseContext({
|
|
1457
|
+
baseContext,
|
|
1458
|
+
candle,
|
|
1459
|
+
symbol,
|
|
1460
|
+
interval
|
|
1461
|
+
});
|
|
1462
|
+
decisionBaseContextCache = { key: cacheKey, context };
|
|
1463
|
+
return context;
|
|
1464
|
+
};
|
|
1370
1465
|
const resolveDecisionPriceContext = () => {
|
|
1371
1466
|
const candle = cachedData[cachedData.length - 1];
|
|
1372
1467
|
if (!candle || !isFiniteNumber(candle.timestamp) || !isFiniteNumber(candle.close)) {
|
|
@@ -1456,6 +1551,7 @@ var createStrategyAPI = ({
|
|
|
1456
1551
|
}),
|
|
1457
1552
|
getCurrentIndicatorsContext,
|
|
1458
1553
|
getBaseContext,
|
|
1554
|
+
getDecisionBaseContext,
|
|
1459
1555
|
getDecisionPriceContext,
|
|
1460
1556
|
getCurrentPosition,
|
|
1461
1557
|
getDirectionalTpSlPrices: (params) => getDirectionalTpSlPrices(params),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tradejs/core",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.15",
|
|
4
4
|
"description": "MIT-licensed browser-safe API for TradeJS config, strategy authoring, figures, and shared helpers.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tradejs",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
}
|
|
101
101
|
},
|
|
102
102
|
"dependencies": {
|
|
103
|
-
"@tradejs/types": "^2.0.
|
|
103
|
+
"@tradejs/types": "^2.0.15",
|
|
104
104
|
"date-fns": "^3.6.0",
|
|
105
105
|
"fast-technical-indicators": "^1.1.4",
|
|
106
106
|
"klinecharts": "10.0.0-alpha9",
|