@tradejs/strategies 2.0.1 → 2.0.2
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/index.js +347 -54
- package/dist/index.mjs +347 -54
- package/package.json +5 -5
package/dist/index.mjs
CHANGED
|
@@ -16481,7 +16481,7 @@ AdaptiveMomentumRibbon addon:
|
|
|
16481
16481
|
- \`quality=4\` additionally allows two narrower continuation pockets: oscillatorStrength >= 1.2 with coin bias conflict, structuralRewardRiskRatio >= 2.2 and volumeRel20 <= 1.2, or Europe-session oscillatorStrength >= 1.5 with effortVsResult <= 120.
|
|
16482
16482
|
- If signal candle range is available, \`signalRangeAtrRatio\` must be >= 1.05 for live approval; weaker signal candles stay in watch mode.
|
|
16483
16483
|
- The local deterministic gate approves LONG by default. SHORT stays in watch mode except for separately calibrated market-breadth shock pockets.
|
|
16484
|
-
- SHORT
|
|
16484
|
+
- SHORT watch-mode approvals use three calibrated pockets: BTC-favored breadth shock, neutral shared-context breadth exhaustion with marketBreadth.advancers <= 0 and effortVsResult <= 800, or low-CMC benchmark OI contraction with BTC net flow <= 0.
|
|
16485
16485
|
- A reference-derivatives rotation pocket can approve q4 when XRP 15m OI 4h change >= 1.6 and TRX 15m OI 4h change <= -0.2. It may override weak signal range and the default SHORT watch mode, but never hard signal invalidation.
|
|
16486
16486
|
- Non-derivatives approvals are demoted when stopDistanceAtr > 4.5 and breakoutBodyAtr > 2.25, because that combination behaves like a chase entry.
|
|
16487
16487
|
- All live approvals require a calibrated market-regime floor: tpDistanceAtr >= 2.9, trendAdx >= 15, and benchmarkRelativeStrength1d <= 4 when available.
|
|
@@ -16493,11 +16493,14 @@ AdaptiveMomentumRibbon addon:
|
|
|
16493
16493
|
`;
|
|
16494
16494
|
var ADAPTIVE_MOMENTUM_RIBBON_PAYLOAD_PROMPT = `
|
|
16495
16495
|
- \`payload.additionalIndicators.adaptiveMomentumRibbonContext\` contains a compact signal summary:
|
|
16496
|
-
signalOsc / oscillatorStrength / signalRangeAtrRatio / stopDistanceAtr / tpDistanceAtr / breakoutBodyAtr / trendAdx / benchmarkRelativeStrength1d / chaseRiskBlocked / approvalRegimeAllowed / approvalRegimeBlockReasons / channelState / channelExtensionPct / invalidationDistancePct / structuralRewardRiskRatio / coinBiasAligned / btcBiasAligned / targetVsBtcAlpha1h / targetVsBtcAlpha4h / spreadBps / cmcAltLiquidityRegime / cmcFearGreedValueChange7d / cmcBtcDominanceChange24hPct / baseDecisionApproveBias / marketBreadthAdvancers / marketBreadthAdvanceDeclineRatio / marketBreadthReturn / shortBreadthShockPocket / shortBreadthNeutralPocket / referenceDerivativesRotationPocket / referenceXrpOiChangePct4h15m / referenceTrxOiChangePct4h15m / q4TargetAlpha1Allowed / q4ContinuationAllowed / q4ContinuationBlockReasons / q4ContinuationRecoveryAllowed / derivativesDirectionAligned / derivativesRiskFlags / derivativesFundingZScore / deterministicQuality / approvalAllowedNow / approvalBlockReasons / riskAnnotations.
|
|
16496
|
+
signalOsc / oscillatorStrength / signalRangeAtrRatio / stopDistanceAtr / tpDistanceAtr / breakoutBodyAtr / trendAdx / benchmarkRelativeStrength1d / chaseRiskBlocked / approvalRegimeAllowed / approvalRegimeBlockReasons / channelState / channelExtensionPct / invalidationDistancePct / structuralRewardRiskRatio / coinBiasAligned / btcBiasAligned / targetVsBtcAlpha1h / targetVsBtcAlpha4h / spreadBps / cmcAltLiquidityRegime / cmcTotalMarketCapUsd / cmcFearGreedValueChange7d / cmcBtcDominanceChange24hPct / benchmarkOiChangePct24h1h / btcReferenceTradeFlowNetBaseDelta / baseDecisionApproveBias / marketBreadthAdvancers / marketBreadthAdvanceDeclineRatio / marketBreadthReturn / shortBreadthShockPocket / shortBreadthNeutralPocket / shortCmcBenchmarkContractionPocket / referenceDerivativesRotationPocket / referenceXrpOiChangePct4h15m / referenceTrxOiChangePct4h15m / q4TargetAlpha1Allowed / q4ContinuationAllowed / q4ContinuationBlockReasons / q4ContinuationRecoveryAllowed / derivativesDirectionAligned / derivativesRiskFlags / derivativesFundingZScore / deterministicQuality / approvalAllowedNow / approvalBlockReasons / riskAnnotations.
|
|
16497
16497
|
- Use this context as the primary strategy-specific interpretation instead of re-deriving it only from generic series.
|
|
16498
16498
|
`;
|
|
16499
16499
|
var SHORT_BREADTH_SHOCK_MARKET_BREADTH_RETURN_MAX = -0.01;
|
|
16500
16500
|
var SHORT_BREADTH_NEUTRAL_EFFORT_VS_RESULT_MAX = 800;
|
|
16501
|
+
var SHORT_CMC_TOTAL_MARKET_CAP_USD_MAX = 229e10;
|
|
16502
|
+
var SHORT_BENCHMARK_OI_CHANGE_PCT_24H_1H_MAX = -4;
|
|
16503
|
+
var SHORT_BTC_REFERENCE_TRADE_FLOW_NET_BASE_DELTA_MAX = 0;
|
|
16501
16504
|
var Q4_TARGET_VS_BTC_ALPHA_1H_MAX = 2.4;
|
|
16502
16505
|
var REFERENCE_XRP_OI_CHANGE_PCT_4H_15M_MIN = 1.6;
|
|
16503
16506
|
var REFERENCE_TRX_OI_CHANGE_PCT_4H_15M_MAX = -0.2;
|
|
@@ -16710,7 +16713,7 @@ var getDeterministicAdaptiveMomentumRibbonQuality = (context) => {
|
|
|
16710
16713
|
return 3;
|
|
16711
16714
|
}
|
|
16712
16715
|
if (context.signalDirection === "SHORT") {
|
|
16713
|
-
return context.shortBreadthShockPocket || context.shortBreadthNeutralPocket || context.referenceDerivativesRotationPocket ? 4 : 3;
|
|
16716
|
+
return context.shortBreadthShockPocket || context.shortBreadthNeutralPocket || context.shortCmcBenchmarkContractionPocket || context.referenceDerivativesRotationPocket ? 4 : 3;
|
|
16714
16717
|
}
|
|
16715
16718
|
if (context.signalDirection === "LONG" && context.cmcAltLiquidityRegime === "btc_favored") {
|
|
16716
16719
|
return 3;
|
|
@@ -16721,12 +16724,12 @@ var getDeterministicAdaptiveMomentumRibbonQuality = (context) => {
|
|
|
16721
16724
|
if (causalMomentumLowEffortPocket) {
|
|
16722
16725
|
return 5;
|
|
16723
16726
|
}
|
|
16727
|
+
if (context.signalDirection === "LONG" && !context.q4TargetAlpha1Allowed) {
|
|
16728
|
+
return 3;
|
|
16729
|
+
}
|
|
16724
16730
|
if (context.referenceDerivativesRotationPocket) {
|
|
16725
16731
|
return 4;
|
|
16726
16732
|
}
|
|
16727
|
-
if (!context.q4TargetAlpha1Allowed) {
|
|
16728
|
-
return 3;
|
|
16729
|
-
}
|
|
16730
16733
|
if (context.q4ContinuationRecoveryAllowed) {
|
|
16731
16734
|
return 4;
|
|
16732
16735
|
}
|
|
@@ -16836,6 +16839,8 @@ var buildAdaptiveMomentumRibbonContext = (signal, additionalIndicators) => {
|
|
|
16836
16839
|
const gateFeaturesRelative = getRecord(gateFeatures?.relative);
|
|
16837
16840
|
const gateFeaturesDecisionHints = getRecord(gateFeatures?.decisionHints);
|
|
16838
16841
|
const baseDerivativesContext = getRecord(baseContext?.derivatives);
|
|
16842
|
+
const baseDerivativesIntervals = getRecord(baseDerivativesContext?.intervals);
|
|
16843
|
+
const baseDerivatives1h = getRecord(baseDerivativesIntervals?.["1h"]);
|
|
16839
16844
|
const referenceDerivativeContexts = getRecord(
|
|
16840
16845
|
baseDerivativesContext?.referenceContexts
|
|
16841
16846
|
);
|
|
@@ -16849,6 +16854,11 @@ var buildAdaptiveMomentumRibbonContext = (signal, additionalIndicators) => {
|
|
|
16849
16854
|
const targetVsBtc = getRecord(relative?.targetVsBtc);
|
|
16850
16855
|
const cmcGlobal = getRecord(relative?.cmcGlobal);
|
|
16851
16856
|
const cmcFearGreed = getRecord(relative?.cmcFearGreed);
|
|
16857
|
+
const referenceTradeFlow = getRecord(relative?.referenceTradeFlow);
|
|
16858
|
+
const referenceTradeFlowBySymbol = getRecord(
|
|
16859
|
+
referenceTradeFlow?.tradeFlowBySymbol
|
|
16860
|
+
);
|
|
16861
|
+
const btcReferenceTradeFlow = getRecord(referenceTradeFlowBySymbol?.BTCUSDT);
|
|
16852
16862
|
const baseMarketBreadth = getRecord(relative?.marketBreadth);
|
|
16853
16863
|
const structureAcceptance = getRecord(structure?.acceptance);
|
|
16854
16864
|
const marketContext = getRecord(additional?.marketContext);
|
|
@@ -16899,12 +16909,21 @@ var buildAdaptiveMomentumRibbonContext = (signal, additionalIndicators) => {
|
|
|
16899
16909
|
);
|
|
16900
16910
|
const referenceDerivativesRotationPocket = referenceXrpOiChangePct4h15m != null && referenceXrpOiChangePct4h15m >= REFERENCE_XRP_OI_CHANGE_PCT_4H_15M_MIN && referenceTrxOiChangePct4h15m != null && referenceTrxOiChangePct4h15m <= REFERENCE_TRX_OI_CHANGE_PCT_4H_15M_MAX;
|
|
16901
16911
|
const cmcAltLiquidityRegime = typeof cmcGlobal?.altLiquidityRegime === "string" && cmcGlobal.altLiquidityRegime.trim().length > 0 ? cmcGlobal.altLiquidityRegime : null;
|
|
16912
|
+
const cmcTotalMarketCapUsd = toFiniteNumberOrNull(
|
|
16913
|
+
cmcGlobal?.totalMarketCapUsd
|
|
16914
|
+
);
|
|
16902
16915
|
const cmcFearGreedValueChange7d = toFiniteNumberOrNull(
|
|
16903
16916
|
cmcFearGreed?.valueChange7d
|
|
16904
16917
|
);
|
|
16905
16918
|
const cmcBtcDominanceChange24hPct = toFiniteNumberOrNull(
|
|
16906
16919
|
cmcGlobal?.btcDominanceChange24hPct
|
|
16907
16920
|
);
|
|
16921
|
+
const benchmarkOiChangePct24h1h = toFiniteNumberOrNull(
|
|
16922
|
+
baseDerivatives1h?.oiChangePct24h
|
|
16923
|
+
);
|
|
16924
|
+
const btcReferenceTradeFlowNetBaseDelta = toFiniteNumberOrNull(
|
|
16925
|
+
btcReferenceTradeFlow?.netBaseDelta
|
|
16926
|
+
);
|
|
16908
16927
|
const baseDecisionApproveBias = gateFeaturesDecisionHints?.approveBias === "support" || gateFeaturesDecisionHints?.approveBias === "neutral" || gateFeaturesDecisionHints?.approveBias === "reject" ? gateFeaturesDecisionHints.approveBias : null;
|
|
16909
16928
|
const marketBreadthAdvanceDeclineRatio = toFiniteNumberOrNull(
|
|
16910
16929
|
marketBreadth?.advanceDeclineRatio
|
|
@@ -16913,6 +16932,7 @@ var buildAdaptiveMomentumRibbonContext = (signal, additionalIndicators) => {
|
|
|
16913
16932
|
const marketBreadthReturn = toFiniteNumberOrNull(gateFeaturesRelative?.marketBreadthReturn) ?? toFiniteNumberOrNull(marketBreadth?.equalWeightedReturn);
|
|
16914
16933
|
const shortBreadthShockPocket = signalDirection === "SHORT" && cmcAltLiquidityRegime === "btc_favored" && marketBreadthAdvanceDeclineRatio != null && marketBreadthAdvanceDeclineRatio <= 0 && marketBreadthReturn != null && marketBreadthReturn <= SHORT_BREADTH_SHOCK_MARKET_BREADTH_RETURN_MAX;
|
|
16915
16934
|
const shortBreadthNeutralPocket = signalDirection === "SHORT" && baseDecisionApproveBias === "neutral" && marketBreadthAdvancers != null && marketBreadthAdvancers <= 0 && marketBreadthReturn != null && marketBreadthReturn <= 0 && isInRange(effortVsResult, 0, SHORT_BREADTH_NEUTRAL_EFFORT_VS_RESULT_MAX);
|
|
16935
|
+
const shortCmcBenchmarkContractionPocket = signalDirection === "SHORT" && cmcTotalMarketCapUsd != null && cmcTotalMarketCapUsd <= SHORT_CMC_TOTAL_MARKET_CAP_USD_MAX && benchmarkOiChangePct24h1h != null && benchmarkOiChangePct24h1h <= SHORT_BENCHMARK_OI_CHANGE_PCT_24H_1H_MAX && btcReferenceTradeFlowNetBaseDelta != null && btcReferenceTradeFlowNetBaseDelta <= SHORT_BTC_REFERENCE_TRADE_FLOW_NET_BASE_DELTA_MAX;
|
|
16916
16936
|
const q4TargetAlpha1Allowed = targetVsBtcAlpha1h == null || targetVsBtcAlpha1h <= Q4_TARGET_VS_BTC_ALPHA_1H_MAX;
|
|
16917
16937
|
const q4ContinuationBlockReasons = getQ4ContinuationBlockReasons({
|
|
16918
16938
|
targetVsBtcAlpha4h,
|
|
@@ -16984,7 +17004,7 @@ var buildAdaptiveMomentumRibbonContext = (signal, additionalIndicators) => {
|
|
|
16984
17004
|
if (signalDirection === "LONG" && derivativesPressure === "crowded_long" || signalDirection === "SHORT" && derivativesPressure === "crowded_short") {
|
|
16985
17005
|
riskAnnotations.push("derivatives_pressure_conflict");
|
|
16986
17006
|
}
|
|
16987
|
-
if (signalDirection === "SHORT" && !(shortBreadthShockPocket || shortBreadthNeutralPocket || referenceDerivativesRotationPocket)) {
|
|
17007
|
+
if (signalDirection === "SHORT" && !(shortBreadthShockPocket || shortBreadthNeutralPocket || shortCmcBenchmarkContractionPocket || referenceDerivativesRotationPocket)) {
|
|
16988
17008
|
approvalBlockReasons.push("short_disabled");
|
|
16989
17009
|
}
|
|
16990
17010
|
if (signalDirection === "LONG" && cmcAltLiquidityRegime === "btc_favored") {
|
|
@@ -17046,14 +17066,18 @@ var buildAdaptiveMomentumRibbonContext = (signal, additionalIndicators) => {
|
|
|
17046
17066
|
spreadBias,
|
|
17047
17067
|
spreadSeverity,
|
|
17048
17068
|
cmcAltLiquidityRegime,
|
|
17069
|
+
cmcTotalMarketCapUsd,
|
|
17049
17070
|
cmcFearGreedValueChange7d,
|
|
17050
17071
|
cmcBtcDominanceChange24hPct,
|
|
17072
|
+
benchmarkOiChangePct24h1h,
|
|
17073
|
+
btcReferenceTradeFlowNetBaseDelta,
|
|
17051
17074
|
baseDecisionApproveBias,
|
|
17052
17075
|
marketBreadthAdvancers,
|
|
17053
17076
|
marketBreadthAdvanceDeclineRatio,
|
|
17054
17077
|
marketBreadthReturn,
|
|
17055
17078
|
shortBreadthShockPocket,
|
|
17056
17079
|
shortBreadthNeutralPocket,
|
|
17080
|
+
shortCmcBenchmarkContractionPocket,
|
|
17057
17081
|
referenceDerivativesRotationPocket,
|
|
17058
17082
|
referenceXrpOiChangePct4h15m,
|
|
17059
17083
|
referenceTrxOiChangePct4h15m,
|
|
@@ -17124,14 +17148,18 @@ var buildAdaptiveMomentumRibbonContext = (signal, additionalIndicators) => {
|
|
|
17124
17148
|
spreadBias,
|
|
17125
17149
|
spreadSeverity,
|
|
17126
17150
|
cmcAltLiquidityRegime,
|
|
17151
|
+
cmcTotalMarketCapUsd,
|
|
17127
17152
|
cmcFearGreedValueChange7d,
|
|
17128
17153
|
cmcBtcDominanceChange24hPct,
|
|
17154
|
+
benchmarkOiChangePct24h1h,
|
|
17155
|
+
btcReferenceTradeFlowNetBaseDelta,
|
|
17129
17156
|
baseDecisionApproveBias,
|
|
17130
17157
|
marketBreadthAdvancers,
|
|
17131
17158
|
marketBreadthAdvanceDeclineRatio,
|
|
17132
17159
|
marketBreadthReturn,
|
|
17133
17160
|
shortBreadthShockPocket,
|
|
17134
17161
|
shortBreadthNeutralPocket,
|
|
17162
|
+
shortCmcBenchmarkContractionPocket,
|
|
17135
17163
|
referenceDerivativesRotationPocket,
|
|
17136
17164
|
referenceXrpOiChangePct4h15m,
|
|
17137
17165
|
referenceTrxOiChangePct4h15m,
|
|
@@ -17270,14 +17298,18 @@ Additional AdaptiveMomentumRibbon context:
|
|
|
17270
17298
|
- spreadBias=${context.spreadBias ?? "n/a"}
|
|
17271
17299
|
- spreadSeverity=${context.spreadSeverity ?? "n/a"}
|
|
17272
17300
|
- cmcAltLiquidityRegime=${context.cmcAltLiquidityRegime ?? "n/a"}
|
|
17301
|
+
- cmcTotalMarketCapUsd=${context.cmcTotalMarketCapUsd?.toFixed?.(0) ?? "n/a"}
|
|
17273
17302
|
- cmcFearGreedValueChange7d=${context.cmcFearGreedValueChange7d?.toFixed?.(3) ?? "n/a"}
|
|
17274
17303
|
- cmcBtcDominanceChange24hPct=${context.cmcBtcDominanceChange24hPct?.toFixed?.(3) ?? "n/a"}
|
|
17304
|
+
- benchmarkOiChangePct24h1h=${context.benchmarkOiChangePct24h1h?.toFixed?.(3) ?? "n/a"}
|
|
17305
|
+
- btcReferenceTradeFlowNetBaseDelta=${context.btcReferenceTradeFlowNetBaseDelta?.toFixed?.(3) ?? "n/a"}
|
|
17275
17306
|
- baseDecisionApproveBias=${context.baseDecisionApproveBias ?? "n/a"}
|
|
17276
17307
|
- marketBreadthAdvancers=${context.marketBreadthAdvancers?.toFixed?.(0) ?? "n/a"}
|
|
17277
17308
|
- marketBreadthAdvanceDeclineRatio=${context.marketBreadthAdvanceDeclineRatio?.toFixed?.(3) ?? "n/a"}
|
|
17278
17309
|
- marketBreadthReturn=${context.marketBreadthReturn?.toFixed?.(5) ?? "n/a"}
|
|
17279
17310
|
- shortBreadthShockPocket=${context.shortBreadthShockPocket}
|
|
17280
17311
|
- shortBreadthNeutralPocket=${context.shortBreadthNeutralPocket}
|
|
17312
|
+
- shortCmcBenchmarkContractionPocket=${context.shortCmcBenchmarkContractionPocket}
|
|
17281
17313
|
- referenceDerivativesRotationPocket=${context.referenceDerivativesRotationPocket}
|
|
17282
17314
|
- referenceXrpOiChangePct4h15m=${context.referenceXrpOiChangePct4h15m?.toFixed?.(3) ?? "n/a"}
|
|
17283
17315
|
- referenceTrxOiChangePct4h15m=${context.referenceTrxOiChangePct4h15m?.toFixed?.(3) ?? "n/a"}
|
|
@@ -17345,6 +17377,9 @@ var MAX_REFERENCE_SHORT_RECOVERY_ETH_LIQ_IMBALANCE_1H = -0.99;
|
|
|
17345
17377
|
var MAX_XRP_SHORT_RECOVERY_BTC_VS_ALT_RETURN_24H = -0.03;
|
|
17346
17378
|
var MAX_XRP_SHORT_RECOVERY_FUNDING_Z_SCORE_1H = -1.8;
|
|
17347
17379
|
var MIN_XRP_OI_REJECT_BIAS_BLOCK_15M = 25e7;
|
|
17380
|
+
var MAX_XRP_OI_RECOVERY_BTC_DOMINANCE_PCT = 58.45;
|
|
17381
|
+
var MIN_XRP_OI_RECOVERY_MARKET_BREADTH_SYMBOLS = 27;
|
|
17382
|
+
var MIN_XRP_OI_RECOVERY_BNB_FUNDING_CHANGE_1H = 0;
|
|
17348
17383
|
var MAX_APPROVAL_RSI = 75;
|
|
17349
17384
|
var MIN_APPROVAL_BB_WIDTH_RANK_100 = 50;
|
|
17350
17385
|
var buildAdaptiveTrendChannelGuardrailContext = ({
|
|
@@ -17353,6 +17388,7 @@ var buildAdaptiveTrendChannelGuardrailContext = ({
|
|
|
17353
17388
|
}) => {
|
|
17354
17389
|
const targetDerivatives1h = baseContext?.derivatives?.intervals?.["1h"];
|
|
17355
17390
|
const ethDerivatives1h = baseContext?.derivatives?.referenceContexts?.["ETHUSDT"]?.intervals?.["1h"];
|
|
17391
|
+
const bnbDerivativesSummary = baseContext?.derivatives?.referenceContexts?.["BNBUSDT"]?.summary;
|
|
17356
17392
|
const xrpDerivatives15m = baseContext?.derivatives?.referenceContexts?.["XRPUSDT"]?.intervals?.["15m"];
|
|
17357
17393
|
const xrpDerivatives1h = baseContext?.derivatives?.referenceContexts?.["XRPUSDT"]?.intervals?.["1h"];
|
|
17358
17394
|
const targetDerivatives1hStale = targetDerivatives1h?.stale === true;
|
|
@@ -17370,10 +17406,17 @@ var buildAdaptiveTrendChannelGuardrailContext = ({
|
|
|
17370
17406
|
baseContext?.regime?.volatility?.percentiles?.bbWidthRank100
|
|
17371
17407
|
);
|
|
17372
17408
|
const trendFollowState = baseContext?.regime?.trend?.trendFollow?.state ?? null;
|
|
17409
|
+
const volatilityState = baseContext?.regime?.volatility?.state ?? null;
|
|
17373
17410
|
const h4VolatilityState = baseContext?.mtf?.summary?.h4VolatilityState ?? null;
|
|
17374
17411
|
const benchmarkTrendAlignment = baseContext?.relative?.benchmark?.trendAlignment ?? null;
|
|
17375
17412
|
const cmcExchangeLiquidityAligned = typeof baseContext?.gateFeatures?.relative?.cmcExchangeLiquidityAligned === "boolean" ? baseContext.gateFeatures.relative.cmcExchangeLiquidityAligned : null;
|
|
17376
17413
|
const cmcExchangeLiquidityStale = typeof baseContext?.gateFeatures?.relative?.cmcExchangeLiquidityStale === "boolean" ? baseContext.gateFeatures.relative.cmcExchangeLiquidityStale : null;
|
|
17414
|
+
const cmcBtcDominancePct = asFiniteNumber(
|
|
17415
|
+
baseContext?.relative?.cmcGlobal?.btcDominancePct
|
|
17416
|
+
);
|
|
17417
|
+
const marketBreadthSymbolsCount = asFiniteNumber(
|
|
17418
|
+
baseContext?.relative?.marketBreadth?.symbolsCount
|
|
17419
|
+
);
|
|
17377
17420
|
const baseApproveBias = baseContext?.gateFeatures?.decisionHints?.approveBias ?? null;
|
|
17378
17421
|
const targetLiqImbalance1h = asFiniteNumber(
|
|
17379
17422
|
targetDerivatives1h?.liqImbalance
|
|
@@ -17384,6 +17427,9 @@ var buildAdaptiveTrendChannelGuardrailContext = ({
|
|
|
17384
17427
|
const targetLiqTotal1h = asFiniteNumber(targetDerivatives1h?.liqTotal);
|
|
17385
17428
|
const ethLiqImbalance1h = asFiniteNumber(ethDerivatives1h?.liqImbalance);
|
|
17386
17429
|
const ethFundingRate1h = asFiniteNumber(ethDerivatives1h?.fundingRate);
|
|
17430
|
+
const bnbFundingChange1h = asFiniteNumber(
|
|
17431
|
+
bnbDerivativesSummary?.fundingChange1h
|
|
17432
|
+
);
|
|
17387
17433
|
const xrpOpenInterest15m = asFiniteNumber(xrpDerivatives15m?.openInterest);
|
|
17388
17434
|
const xrpPriceOiDivergenceType = baseContext?.derivatives?.referenceContexts?.["XRPUSDT"]?.summary?.priceOiDivergenceType ?? null;
|
|
17389
17435
|
const xrpFundingZScore1h = asFiniteNumber(xrpDerivatives1h?.fundingZScore);
|
|
@@ -17421,10 +17467,11 @@ var buildAdaptiveTrendChannelGuardrailContext = ({
|
|
|
17421
17467
|
const xrpBtcShortRecoverySetup = direction === "SHORT" && xrpDerivatives1hStale !== true && xrpPriceOiDivergenceType === "price_down_oi_up" && btcVsAltReturn24h != null && btcVsAltReturn24h <= MAX_XRP_SHORT_RECOVERY_BTC_VS_ALT_RETURN_24H && xrpFundingZScore1h != null && xrpFundingZScore1h <= MAX_XRP_SHORT_RECOVERY_FUNDING_Z_SCORE_1H;
|
|
17422
17468
|
const xrpEthShortRecoverySetup = direction === "SHORT" && xrpDerivatives1hStale !== true && ethDerivatives1hStale !== true && xrpPriceOiDivergenceType === "price_down_oi_up" && xrpFundingZScore1h != null && xrpFundingZScore1h <= MAX_XRP_SHORT_RECOVERY_FUNDING_Z_SCORE_1H && ethLiqImbalance1h != null && ethLiqImbalance1h <= MAX_REFERENCE_SHORT_RECOVERY_ETH_LIQ_IMBALANCE_1H;
|
|
17423
17469
|
const xrpShortRecoverySetup = xrpBtcShortRecoverySetup || xrpEthShortRecoverySetup;
|
|
17424
|
-
|
|
17470
|
+
const xrpOiReferenceRecoverySetup = xrpOpenInterest15m != null && xrpOpenInterest15m >= MIN_XRP_OI_REJECT_BIAS_BLOCK_15M && baseApproveBias === "reject" && volatilityState === "expanded" && cmcBtcDominancePct != null && cmcBtcDominancePct <= MAX_XRP_OI_RECOVERY_BTC_DOMINANCE_PCT && marketBreadthSymbolsCount != null && marketBreadthSymbolsCount >= MIN_XRP_OI_RECOVERY_MARKET_BREADTH_SYMBOLS && bnbFundingChange1h != null && bnbFundingChange1h >= MIN_XRP_OI_RECOVERY_BNB_FUNDING_CHANGE_1H;
|
|
17471
|
+
if (xrpOpenInterest15m != null && xrpOpenInterest15m >= MIN_XRP_OI_REJECT_BIAS_BLOCK_15M && baseApproveBias === "reject" && !xrpShortRecoverySetup && !xrpOiReferenceRecoverySetup) {
|
|
17425
17472
|
hardBlockReasons.push("xrp_oi_reject_bias");
|
|
17426
17473
|
}
|
|
17427
|
-
const approvalSetup = longApprovalSetup || xrpShortRecoverySetup;
|
|
17474
|
+
const approvalSetup = longApprovalSetup || xrpShortRecoverySetup || xrpOiReferenceRecoverySetup;
|
|
17428
17475
|
const highConfidenceSetup = longApprovalSetup && breakoutDistancePct >= MIN_HIGH_CONFIDENCE_BREAKOUT_DISTANCE_PCT && channelWidthPct >= MIN_HIGH_CONFIDENCE_CHANNEL_WIDTH_PCT;
|
|
17429
17476
|
let deterministicQuality = 3;
|
|
17430
17477
|
if (hardBlockReasons.length > 0) {
|
|
@@ -17482,15 +17529,19 @@ var buildAdaptiveTrendChannelGuardrailContext = ({
|
|
|
17482
17529
|
rsi,
|
|
17483
17530
|
bbWidthRank100,
|
|
17484
17531
|
trendFollowState,
|
|
17532
|
+
volatilityState,
|
|
17485
17533
|
h4VolatilityState,
|
|
17486
17534
|
benchmarkTrendAlignment,
|
|
17487
17535
|
cmcExchangeLiquidityAligned,
|
|
17488
17536
|
cmcExchangeLiquidityStale,
|
|
17537
|
+
cmcBtcDominancePct,
|
|
17538
|
+
marketBreadthSymbolsCount,
|
|
17489
17539
|
targetLiqImbalance1h,
|
|
17490
17540
|
targetLiqSpikeRatio1h,
|
|
17491
17541
|
targetLiqTotal1h,
|
|
17492
17542
|
ethLiqImbalance1h,
|
|
17493
17543
|
ethFundingRate1h,
|
|
17544
|
+
bnbFundingChange1h,
|
|
17494
17545
|
xrpOpenInterest15m,
|
|
17495
17546
|
xrpPriceOiDivergenceType,
|
|
17496
17547
|
xrpFundingZScore1h,
|
|
@@ -17566,13 +17617,17 @@ Additional AdaptiveTrendChannel context:
|
|
|
17566
17617
|
- rsi=${String(context.rsi ?? "n/a")}
|
|
17567
17618
|
- bbWidthRank100=${String(context.bbWidthRank100 ?? "n/a")}
|
|
17568
17619
|
- trendFollowState=${context.trendFollowState ?? "n/a"}
|
|
17620
|
+
- volatilityState=${context.volatilityState ?? "n/a"}
|
|
17569
17621
|
- h4VolatilityState=${context.h4VolatilityState ?? "n/a"}
|
|
17570
17622
|
- benchmarkTrendAlignment=${context.benchmarkTrendAlignment ?? "n/a"}
|
|
17623
|
+
- cmcBtcDominancePct=${String(context.cmcBtcDominancePct ?? "n/a")}
|
|
17624
|
+
- marketBreadthSymbolsCount=${String(context.marketBreadthSymbolsCount ?? "n/a")}
|
|
17571
17625
|
- targetLiqImbalance1h=${String(context.targetLiqImbalance1h ?? "n/a")}
|
|
17572
17626
|
- targetLiqSpikeRatio1h=${String(context.targetLiqSpikeRatio1h ?? "n/a")}
|
|
17573
17627
|
- targetLiqTotal1h=${String(context.targetLiqTotal1h ?? "n/a")}
|
|
17574
17628
|
- ethLiqImbalance1h=${String(context.ethLiqImbalance1h ?? "n/a")}
|
|
17575
17629
|
- ethFundingRate1h=${String(context.ethFundingRate1h ?? "n/a")}
|
|
17630
|
+
- bnbFundingChange1h=${String(context.bnbFundingChange1h ?? "n/a")}
|
|
17576
17631
|
- xrpOpenInterest15m=${String(context.xrpOpenInterest15m ?? "n/a")}
|
|
17577
17632
|
- xrpPriceOiDivergenceType=${context.xrpPriceOiDivergenceType ?? "n/a"}
|
|
17578
17633
|
- xrpFundingZScore1h=${String(context.xrpFundingZScore1h ?? "n/a")}
|
|
@@ -17590,7 +17645,7 @@ Interpretation rules for AdaptiveTrendChannel:
|
|
|
17590
17645
|
- The centerline is the adaptive rail; floor/roof are volatility-scaled invalidation bands.
|
|
17591
17646
|
- Prefer flips with reasonable distance from the centerline and confirmation from shared market context.
|
|
17592
17647
|
- Thin participation, missing shared-context confirmation, or missing liquidation-shock recovery evidence should downgrade the setup.
|
|
17593
|
-
- A high-XRP-OI reject bias should remain blocked unless a narrow XRP reference SHORT recovery setup is present.
|
|
17648
|
+
- A high-XRP-OI reject bias should remain blocked unless a narrow XRP reference SHORT recovery setup or expanded CMC/BNB/breadth recovery setup is present.
|
|
17594
17649
|
- Treat deterministicQuality and approvalAllowedNow as the local normalized gate result.
|
|
17595
17650
|
`.trim();
|
|
17596
17651
|
},
|
|
@@ -17807,6 +17862,7 @@ var buildEntryStopTargetFigures = ({
|
|
|
17807
17862
|
var MFR_CALIBRATED_LONG_TARGET_VS_BTC_RATIO_RETURN_24H_MAX = -3.3;
|
|
17808
17863
|
var MFR_CALIBRATED_LONG_ETH_VS_BTC_VOLUME_RATIO_MIN = 0.54;
|
|
17809
17864
|
var MFR_CALIBRATED_LONG_H1_RANGE_POSITION_MAX = 0.08;
|
|
17865
|
+
var MFR_AI_LONG_STOP_DISTANCE_ATR_MIN = 24;
|
|
17810
17866
|
var getMarketFlushReversalLongReboundPocketFeatures = (baseContext) => ({
|
|
17811
17867
|
targetVsBtcRatioReturn24h: toFiniteNumberOrNull2(
|
|
17812
17868
|
baseContext?.relative?.targetVsBtc?.ratioReturn24h
|
|
@@ -17824,6 +17880,21 @@ var isMarketFlushReversalCalibratedLongReboundPocket = ({
|
|
|
17824
17880
|
ethVsBtcVolumeRatio,
|
|
17825
17881
|
h1RangePosition
|
|
17826
17882
|
}) => direction === "LONG" && targetVsBtcRatioReturn24h != null && targetVsBtcRatioReturn24h <= MFR_CALIBRATED_LONG_TARGET_VS_BTC_RATIO_RETURN_24H_MAX && (ethVsBtcVolumeRatio != null && ethVsBtcVolumeRatio >= MFR_CALIBRATED_LONG_ETH_VS_BTC_VOLUME_RATIO_MIN || h1RangePosition != null && h1RangePosition <= MFR_CALIBRATED_LONG_H1_RANGE_POSITION_MAX);
|
|
17883
|
+
var getMarketFlushReversalAiLongPocketFeatures = (baseContext) => ({
|
|
17884
|
+
stopDistanceAtr: toFiniteNumberOrNull2(
|
|
17885
|
+
baseContext?.gateFeatures?.setup?.stopDistanceAtr
|
|
17886
|
+
),
|
|
17887
|
+
cmcIndexRegime: baseContext?.relative?.cmcIndexes?.indexRegime ?? null,
|
|
17888
|
+
cmcIndexStale: typeof baseContext?.relative?.cmcIndexes?.stale === "boolean" ? baseContext.relative.cmcIndexes.stale : null,
|
|
17889
|
+
rsiState: baseContext?.regime?.momentum?.rsiState ?? null
|
|
17890
|
+
});
|
|
17891
|
+
var isMarketFlushReversalValidatedAiLongPocket = ({
|
|
17892
|
+
direction,
|
|
17893
|
+
stopDistanceAtr,
|
|
17894
|
+
cmcIndexRegime,
|
|
17895
|
+
cmcIndexStale,
|
|
17896
|
+
rsiState
|
|
17897
|
+
}) => direction === "LONG" && stopDistanceAtr != null && stopDistanceAtr >= MFR_AI_LONG_STOP_DISTANCE_ATR_MIN && cmcIndexRegime === "risk_off" && cmcIndexStale === false && rsiState === "oversold";
|
|
17827
17898
|
|
|
17828
17899
|
// src/MarketFlushReversal/guardrails.ts
|
|
17829
17900
|
var toFiniteNumberOrNull3 = (value) => {
|
|
@@ -17913,6 +17984,12 @@ var buildMarketFlushReversalGuardrailContext = ({
|
|
|
17913
17984
|
direction
|
|
17914
17985
|
});
|
|
17915
17986
|
const { targetVsBtcRatioReturn24h, ethVsBtcVolumeRatio, h1RangePosition } = longReboundPocketFeatures;
|
|
17987
|
+
const aiLongPocketFeatures = getMarketFlushReversalAiLongPocketFeatures(baseContext);
|
|
17988
|
+
const validatedAiLongPocket = isMarketFlushReversalValidatedAiLongPocket({
|
|
17989
|
+
...aiLongPocketFeatures,
|
|
17990
|
+
direction
|
|
17991
|
+
});
|
|
17992
|
+
const { stopDistanceAtr, cmcIndexRegime, cmcIndexStale, rsiState } = aiLongPocketFeatures;
|
|
17916
17993
|
const approvalBlockReasons = [];
|
|
17917
17994
|
const riskAnnotations = [];
|
|
17918
17995
|
if (direction == null) approvalBlockReasons.push("missing_direction");
|
|
@@ -17923,22 +18000,22 @@ var buildMarketFlushReversalGuardrailContext = ({
|
|
|
17923
18000
|
approvalBlockReasons.push("local_participation_not_confirmed");
|
|
17924
18001
|
}
|
|
17925
18002
|
if (!marketContextAvailable) {
|
|
17926
|
-
|
|
18003
|
+
riskAnnotations.push("missing_broad_market_derivatives");
|
|
17927
18004
|
}
|
|
17928
18005
|
if (marketRiskFlags.includes("stale_derivatives")) {
|
|
17929
|
-
|
|
18006
|
+
riskAnnotations.push("stale_broad_market_derivatives");
|
|
17930
18007
|
}
|
|
17931
18008
|
if (marketContextAvailable && broadMarketFlushDirection == null) {
|
|
17932
|
-
|
|
18009
|
+
riskAnnotations.push("no_broad_market_flush");
|
|
17933
18010
|
}
|
|
17934
18011
|
if (direction != null && broadMarketFlushDirection != null && broadMarketFlushDirection !== direction) {
|
|
17935
|
-
|
|
18012
|
+
riskAnnotations.push("broad_market_flush_direction_mismatch");
|
|
17936
18013
|
}
|
|
17937
18014
|
if (direction === "SHORT") {
|
|
17938
18015
|
approvalBlockReasons.push("short_flush_rebound_pocket_not_validated");
|
|
17939
18016
|
}
|
|
17940
|
-
if (direction === "LONG" && !
|
|
17941
|
-
approvalBlockReasons.push("
|
|
18017
|
+
if (direction === "LONG" && !validatedAiLongPocket) {
|
|
18018
|
+
approvalBlockReasons.push("validated_long_ai_pocket_missing");
|
|
17942
18019
|
}
|
|
17943
18020
|
if (signalContext.marketFlushConfirmed !== true) {
|
|
17944
18021
|
riskAnnotations.push("market_flush_not_available_at_core_time");
|
|
@@ -17962,7 +18039,12 @@ var buildMarketFlushReversalGuardrailContext = ({
|
|
|
17962
18039
|
targetVsBtcRatioReturn24h,
|
|
17963
18040
|
ethVsBtcVolumeRatio,
|
|
17964
18041
|
h1RangePosition,
|
|
17965
|
-
calibratedLongRebound
|
|
18042
|
+
calibratedLongRebound,
|
|
18043
|
+
stopDistanceAtr,
|
|
18044
|
+
cmcIndexRegime,
|
|
18045
|
+
cmcIndexStale,
|
|
18046
|
+
rsiState,
|
|
18047
|
+
validatedAiLongPocket
|
|
17966
18048
|
};
|
|
17967
18049
|
return {
|
|
17968
18050
|
...signalContext,
|
|
@@ -18061,6 +18143,11 @@ Additional Market Flush Reversal context:
|
|
|
18061
18143
|
- ethVsBtcVolumeRatio=${String(context.marketFlushReversalGateFeatures.ethVsBtcVolumeRatio ?? "n/a")}
|
|
18062
18144
|
- h1RangePosition=${String(context.marketFlushReversalGateFeatures.h1RangePosition ?? "n/a")}
|
|
18063
18145
|
- calibratedLongRebound=${String(context.marketFlushReversalGateFeatures.calibratedLongRebound)}
|
|
18146
|
+
- stopDistanceAtr=${String(context.marketFlushReversalGateFeatures.stopDistanceAtr ?? "n/a")}
|
|
18147
|
+
- cmcIndexRegime=${context.marketFlushReversalGateFeatures.cmcIndexRegime ?? "n/a"}
|
|
18148
|
+
- cmcIndexStale=${String(context.marketFlushReversalGateFeatures.cmcIndexStale ?? "n/a")}
|
|
18149
|
+
- rsiState=${context.marketFlushReversalGateFeatures.rsiState ?? "n/a"}
|
|
18150
|
+
- validatedAiLongPocket=${String(context.marketFlushReversalGateFeatures.validatedAiLongPocket)}
|
|
18064
18151
|
- approvalAllowedNow=${String(context.approvalAllowedNow)}
|
|
18065
18152
|
- deterministicQuality=${String(context.deterministicQuality)}
|
|
18066
18153
|
- approvalBlockReasons=${context.approvalBlockReasons.join(",") || "none"}
|
|
@@ -18173,6 +18260,7 @@ var buildDoubleTapGateFeatures = ({
|
|
|
18173
18260
|
defaultApprovalAllowed,
|
|
18174
18261
|
q4AltDispersionOk,
|
|
18175
18262
|
q4DerivativesCmcRiskOk,
|
|
18263
|
+
q4DerivativesDirectionSessionOk,
|
|
18176
18264
|
strictMomentumApproved,
|
|
18177
18265
|
strictMomentumRoc1dOk
|
|
18178
18266
|
}) => {
|
|
@@ -18195,6 +18283,7 @@ var buildDoubleTapGateFeatures = ({
|
|
|
18195
18283
|
q4AltDispersionOk,
|
|
18196
18284
|
q4DerivativesPocket,
|
|
18197
18285
|
q4DerivativesCmcRiskOk,
|
|
18286
|
+
q4DerivativesDirectionSessionOk,
|
|
18198
18287
|
strictMomentumApproved,
|
|
18199
18288
|
strictMomentumRoc1dOk
|
|
18200
18289
|
};
|
|
@@ -18373,7 +18462,8 @@ var buildDoubleTapAiContext = (payload) => {
|
|
|
18373
18462
|
const q4CmcApproval = legacyShapeCandidate && !legacyHighPrecisionShapeCandidate && baseIndicatorCandidate && cmcBtcDominanceChange24hPct != null && cmcBtcDominanceChange24hPct > Q4_CMC_BTC_DOMINANCE_CHANGE_MIN && cmcBtcDominanceChange24hPct <= Q4_CMC_BTC_DOMINANCE_CHANGE_MAX && altDispersion24h != null && altDispersion24h < Q4_ALT_DISPERSION_24H_MAX;
|
|
18374
18463
|
const q4DerivativesBadCmcPocket = btcVsAltReturn24h != null && cmc20ToCmc100RatioChange24hPct != null && btcVsAltReturn24h <= Q4_DERIVATIVES_BAD_BTC_VS_ALT_RETURN_24H_MAX && cmc20ToCmc100RatioChange24hPct <= Q4_DERIVATIVES_BAD_CMC20_TO_CMC100_CHANGE_24H_MAX;
|
|
18375
18464
|
const q4DerivativesPocket = baseContextAvailable && btcVsAltReturn24h != null && ethCrowdingPersistenceBars != null && solFundingZScore15m != null && btcVsAltReturn24h <= Q4_DERIVATIVES_BTC_VS_ALT_RETURN_24H_MAX && ethCrowdingPersistenceBars >= Q4_DERIVATIVES_ETH_CROWDING_PERSISTENCE_MIN && solFundingZScore15m <= Q4_DERIVATIVES_SOL_FUNDING_Z_SCORE_15M_MAX;
|
|
18376
|
-
const
|
|
18465
|
+
const q4DerivativesDirectionSessionOk = q4DerivativesPocket ? signalDirection === "LONG" ? primarySession === "europe" : signalDirection === "SHORT" ? true : false : null;
|
|
18466
|
+
const q4DerivativesApproval = q4DerivativesPocket && q4DerivativesDirectionSessionOk === true && !q4DerivativesBadCmcPocket;
|
|
18377
18467
|
const softBlockReasons = [
|
|
18378
18468
|
...legacyShapeCandidate && sessionWindowPhase !== "active" ? ["inactive_session_window"] : [],
|
|
18379
18469
|
...legacyShapeCandidate && (executionScore == null || executionScore < MIN_EXECUTION_SCORE_FOR_AI_GATE) ? ["low_or_missing_execution_score"] : [],
|
|
@@ -18386,7 +18476,9 @@ var buildDoubleTapAiContext = (payload) => {
|
|
|
18386
18476
|
...legacyShapeCandidate && !legacyHighPrecisionShapeCandidate && cmcBtcDominanceChange24hPct != null && (cmcBtcDominanceChange24hPct <= Q4_CMC_BTC_DOMINANCE_CHANGE_MIN || cmcBtcDominanceChange24hPct > Q4_CMC_BTC_DOMINANCE_CHANGE_MAX) ? ["cmc_btc_dominance_change_outside_band"] : [],
|
|
18387
18477
|
...legacyShapeCandidate && !legacyHighPrecisionShapeCandidate && cmcBtcDominanceChange24hPct != null && cmcBtcDominanceChange24hPct > Q4_CMC_BTC_DOMINANCE_CHANGE_MIN && cmcBtcDominanceChange24hPct <= Q4_CMC_BTC_DOMINANCE_CHANGE_MAX && altDispersion24h == null ? ["missing_alt_dispersion_24h_for_q4"] : [],
|
|
18388
18478
|
...legacyShapeCandidate && !legacyHighPrecisionShapeCandidate && altDispersion24h != null && altDispersion24h >= Q4_ALT_DISPERSION_24H_MAX ? ["alt_dispersion_24h_too_high_for_q4"] : [],
|
|
18389
|
-
...q4CmcApproval ? ["legacy_q4_structural_observation_only"] : []
|
|
18479
|
+
...q4CmcApproval ? ["legacy_q4_structural_observation_only"] : [],
|
|
18480
|
+
...q4DerivativesPocket && signalDirection === "LONG" && q4DerivativesDirectionSessionOk === false ? ["long_q4_derivatives_outside_europe_session"] : [],
|
|
18481
|
+
...q4DerivativesPocket && signalDirection == null ? ["missing_signal_direction_for_q4_derivatives"] : []
|
|
18390
18482
|
];
|
|
18391
18483
|
const highPrecisionApprovalBlocked = legacyHighPrecisionShapeCandidate && !highPrecisionCmcApproval && !q4DerivativesApproval;
|
|
18392
18484
|
const q4DerivativesApprovalBlocked = q4DerivativesPocket && !q4DerivativesApproval && !highPrecisionCmcApproval;
|
|
@@ -18422,6 +18514,7 @@ var buildDoubleTapAiContext = (payload) => {
|
|
|
18422
18514
|
defaultApprovalAllowed,
|
|
18423
18515
|
q4AltDispersionOk: altDispersion24h == null ? null : altDispersion24h < Q4_ALT_DISPERSION_24H_MAX,
|
|
18424
18516
|
q4DerivativesCmcRiskOk: btcVsAltReturn24h == null || cmc20ToCmc100RatioChange24hPct == null ? null : !q4DerivativesBadCmcPocket,
|
|
18517
|
+
q4DerivativesDirectionSessionOk,
|
|
18425
18518
|
strictMomentumApproved: strictMomentumApprovalAllowedNow,
|
|
18426
18519
|
strictMomentumRoc1dOk
|
|
18427
18520
|
});
|
|
@@ -18455,6 +18548,7 @@ var buildDoubleTapAiContext = (payload) => {
|
|
|
18455
18548
|
ethCrowdingPersistenceBars,
|
|
18456
18549
|
solFundingZScore15m,
|
|
18457
18550
|
altDispersion24h,
|
|
18551
|
+
q4DerivativesDirectionSessionOk,
|
|
18458
18552
|
doubleTapGateFeatures,
|
|
18459
18553
|
structuralHardBlockReasons,
|
|
18460
18554
|
softBlockReasons,
|
|
@@ -18559,6 +18653,7 @@ Additional DoubleTap context:
|
|
|
18559
18653
|
- doubleTapGateQ4AltDispersionOk=${String(context.doubleTapGateFeatures.q4AltDispersionOk ?? "n/a")}
|
|
18560
18654
|
- doubleTapGateQ4DerivativesPocket=${String(context.doubleTapGateFeatures.q4DerivativesPocket)}
|
|
18561
18655
|
- doubleTapGateQ4DerivativesCmcRiskOk=${String(context.doubleTapGateFeatures.q4DerivativesCmcRiskOk ?? "n/a")}
|
|
18656
|
+
- doubleTapGateQ4DerivativesDirectionSessionOk=${String(context.doubleTapGateFeatures.q4DerivativesDirectionSessionOk ?? "n/a")}
|
|
18562
18657
|
- doubleTapGateStrictMomentumApproved=${String(context.doubleTapGateFeatures.strictMomentumApproved)}
|
|
18563
18658
|
- doubleTapGateStrictMomentumRoc1dOk=${String(context.doubleTapGateFeatures.strictMomentumRoc1dOk ?? "n/a")}
|
|
18564
18659
|
- deterministicQuality=${String(context.deterministicQuality)}
|
|
@@ -18576,7 +18671,7 @@ Interpretation rules for DoubleTap:
|
|
|
18576
18671
|
- Treat deterministicQuality and approvalAllowedNow as the normalized local gate result.
|
|
18577
18672
|
- Local q5 approval needs the high-precision pocket plus active session window, execution score >= 35, lowTouchCount20 >= 1, aligned volume structure, no benchmark conflict, and CMC alt volume change <= 0.5.
|
|
18578
18673
|
- The legacy structural q4 CMC pocket is retained only as observation context and should not be treated as local approval.
|
|
18579
|
-
- Local q4 approval comes from the derivatives reference pocket: BTC underperforms alts by at least 0.9%, ETH crowding persistence >= 140, SOL 15m funding z-score <= 0.2, unless BTC underperforms alts by at least 1.4% while CMC20/CMC100 ratio change <= -0.0007.
|
|
18674
|
+
- Local q4 approval comes from the derivatives reference pocket: BTC underperforms alts by at least 0.9%, ETH crowding persistence >= 140, SOL 15m funding z-score <= 0.2, unless BTC underperforms alts by at least 1.4% while CMC20/CMC100 ratio change <= -0.0007; LONG q4 derivatives approval additionally requires the Europe session, while SHORT q4 derivatives approval has no session-side restriction.
|
|
18580
18675
|
- Main local approval additionally needs strict momentum confirmation with ROC1D >= -5.25 for q5 approval; the derivatives reference q4 pocket is already momentum/positioning filtered and does not require that ROC gate.
|
|
18581
18676
|
- A good long has two comparable lows and a clean close above the neckline.
|
|
18582
18677
|
- A good short has two comparable highs and a clean close below the neckline.
|
|
@@ -18660,6 +18755,8 @@ var MAX_APPROVAL_PRICE_DISTANCE_TO_MA_SLOW_ATR = 1.2;
|
|
|
18660
18755
|
var MIN_APPROVAL_ACTIVE_LIQUIDITY_ZONES = 1;
|
|
18661
18756
|
var MAX_DERIVATIVES_RISK_OFF_ALT_BASKET_RETURN_24H = -0.035;
|
|
18662
18757
|
var MAX_DERIVATIVES_RISK_OFF_TRX_OI_CHANGE_PCT_4H = -1.8;
|
|
18758
|
+
var MIN_BENCHMARK_FLOW_BUY_PRESSURE_PCT = 0.61;
|
|
18759
|
+
var MIN_BENCHMARK_OI_ACCELERATION = 0.55;
|
|
18663
18760
|
var Q4_APPROVAL_ATR_RANK_BUCKETS = /* @__PURE__ */ new Set(["high", "extreme"]);
|
|
18664
18761
|
var buildLiquidityTailsGateFeatures = ({
|
|
18665
18762
|
signalContext,
|
|
@@ -18764,10 +18861,17 @@ var buildLiquidityTailsGuardrailContext = ({
|
|
|
18764
18861
|
const flushSupport = direction === "LONG" ? derivativesRiskFlags.includes("short_liquidation_spike") || derivativesPressure === "short_flush" : direction === "SHORT" ? derivativesRiskFlags.includes("long_liquidation_spike") || derivativesPressure === "long_flush" : false;
|
|
18765
18862
|
const directionalCrowding = direction === "LONG" ? derivativesRiskFlags.includes("crowded_long") : direction === "SHORT" ? derivativesRiskFlags.includes("crowded_short") : false;
|
|
18766
18863
|
const derivativesRiskOffLongRecoveryPocket = direction === "LONG" && cmcFearGreedValue != null && cmcFearGreedValue <= MAX_APPROVAL_CMC_FEAR_GREED_VALUE && altBasketReturn24h != null && altBasketReturn24h <= MAX_DERIVATIVES_RISK_OFF_ALT_BASKET_RETURN_24H && referenceTrx1hStale === false && referenceTrx1hOiChangePct4h != null && referenceTrx1hOiChangePct4h <= MAX_DERIVATIVES_RISK_OFF_TRX_OI_CHANGE_PCT_4H;
|
|
18767
|
-
|
|
18864
|
+
const referenceTradeFlowBuyPressurePct = asFiniteNumber2(
|
|
18865
|
+
baseContext?.gateFeatures?.participation?.referenceTradeFlowBuyPressurePct
|
|
18866
|
+
);
|
|
18867
|
+
const benchmarkOiAcceleration = asFiniteNumber2(
|
|
18868
|
+
derivativesSummary?.oiAcceleration
|
|
18869
|
+
);
|
|
18870
|
+
const benchmarkFlowOiExpansionRecoveryPocket = (direction === "LONG" || direction === "SHORT") && q4AtrRankEligible && referenceTradeFlowBuyPressurePct != null && referenceTradeFlowBuyPressurePct >= MIN_BENCHMARK_FLOW_BUY_PRESSURE_PCT && benchmarkOiAcceleration != null && benchmarkOiAcceleration >= MIN_BENCHMARK_OI_ACCELERATION;
|
|
18871
|
+
if (derivativesDirectionAligned === true && !flushSupport && !derivativesRiskOffLongRecoveryPocket && !benchmarkFlowOiExpansionRecoveryPocket) {
|
|
18768
18872
|
hardBlockReasons.push("derivatives_reversal_aligned");
|
|
18769
18873
|
}
|
|
18770
|
-
if (derivativesDirectionAligned === false && !flushSupport && !derivativesRiskOffLongRecoveryPocket) {
|
|
18874
|
+
if (derivativesDirectionAligned === false && !flushSupport && !derivativesRiskOffLongRecoveryPocket && !benchmarkFlowOiExpansionRecoveryPocket) {
|
|
18771
18875
|
hardBlockReasons.push("derivatives_reversal_conflict");
|
|
18772
18876
|
}
|
|
18773
18877
|
if (volumeRel20 != null && volumeRel20 < 0.75) {
|
|
@@ -18857,6 +18961,9 @@ var buildLiquidityTailsGuardrailContext = ({
|
|
|
18857
18961
|
softBlockReasons.push(...approvalContextReasons);
|
|
18858
18962
|
}
|
|
18859
18963
|
}
|
|
18964
|
+
if (deterministicQuality < 4 && hardBlockReasons.length === 0 && benchmarkFlowOiExpansionRecoveryPocket) {
|
|
18965
|
+
deterministicQuality = 4;
|
|
18966
|
+
}
|
|
18860
18967
|
return {
|
|
18861
18968
|
...signalContext,
|
|
18862
18969
|
baseContextAvailable: Boolean(baseContext),
|
|
@@ -18887,6 +18994,7 @@ var buildLiquidityTailsGuardrailContext = ({
|
|
|
18887
18994
|
derivativesRiskFlags,
|
|
18888
18995
|
cadenceUpgradePocket,
|
|
18889
18996
|
derivativesRiskOffLongRecoveryPocket,
|
|
18997
|
+
benchmarkFlowOiExpansionRecoveryPocket,
|
|
18890
18998
|
liquidityTailsGateFeatures,
|
|
18891
18999
|
hardBlockReasons,
|
|
18892
19000
|
softBlockReasons,
|
|
@@ -19057,6 +19165,9 @@ var isDirectionalPriceAboveLevel = ({
|
|
|
19057
19165
|
price,
|
|
19058
19166
|
level
|
|
19059
19167
|
}) => direction === "LONG" ? price != null && level != null && price > level : direction === "SHORT" ? price != null && level != null && price < level : null;
|
|
19168
|
+
var TRANSITION_LOW_TOUCH_COUNT_MAX = 2;
|
|
19169
|
+
var ETH_REFERENCE_WEAK_NON_STRESS_OI_CHANGE_PCT_24H_MAX = -2.5;
|
|
19170
|
+
var LONG_DIRECT_INDICATOR_SUPPORT_MIN = 2;
|
|
19060
19171
|
var buildLiquidityZonesGuardrailContext = ({
|
|
19061
19172
|
signalContext,
|
|
19062
19173
|
baseContext
|
|
@@ -19217,12 +19328,15 @@ var buildLiquidityZonesGuardrailContext = ({
|
|
|
19217
19328
|
const isContinuationBreakoutRetest = direction === "LONG" ? breakoutState === "above_high_level" || entryLocation === "breakout" : direction === "SHORT" ? breakoutState === "below_low_level" || entryLocation === "breakdown" : false;
|
|
19218
19329
|
const hasBaseRetestConfirmation = filterMetric >= 3 && hitCount >= 2 && reactionCloseDistancePct >= 0.08 && retestPenetrationPct <= 90;
|
|
19219
19330
|
const ethReferenceOiWeakPocket = ethReferenceOiChangePct4h != null && ethReferenceOiChangePct4h <= -0.8;
|
|
19220
|
-
const transitionStructureExpansionPocket = hasBaseRetestConfirmation && structureZoneState === "transition" && structureScore != null && structureScore >= 17 && adaptiveChannelFlipDown === false && !directionalCrowding && !ethReferenceOiWeakPocket;
|
|
19221
19331
|
const ethReferenceStressPocket = hasBaseRetestConfirmation && lowTouchCount20 != null && lowTouchCount20 <= 3 && ethReferenceOiChangePct24h != null && ethReferenceOiChangePct24h <= -5.8 && ethReferenceFundingZScore != null && ethReferenceFundingZScore <= -1.05;
|
|
19332
|
+
const transitionStructureExpansionPocket = hasBaseRetestConfirmation && lowTouchCount20 != null && lowTouchCount20 <= TRANSITION_LOW_TOUCH_COUNT_MAX && structureZoneState === "transition" && structureScore != null && structureScore >= 17 && adaptiveChannelFlipDown === false && !directionalCrowding && !ethReferenceOiWeakPocket;
|
|
19222
19333
|
const solReferenceStressPocket = hasBaseRetestConfirmation && lowTouchCount20 != null && lowTouchCount20 <= 3 && solReferenceOiChangePct24h != null && solReferenceOiChangePct24h <= -4.2 && solReferenceFundingZScore != null && solReferenceFundingZScore <= -1.2;
|
|
19223
19334
|
const calibratedExpansionPocket = transitionStructureExpansionPocket || ethReferenceStressPocket || solReferenceStressPocket;
|
|
19335
|
+
const ethReferenceWeakNonStressPocket = ethReferenceOiChangePct24h != null && ethReferenceOiChangePct24h <= ETH_REFERENCE_WEAK_NON_STRESS_OI_CHANGE_PCT_24H_MAX && !ethReferenceStressPocket;
|
|
19336
|
+
const longDirectIndicatorSupportConfirmed = direction === "LONG" ? directIndicatorSupportCount != null && directIndicatorSupportCount >= LONG_DIRECT_INDICATOR_SUPPORT_MIN : null;
|
|
19224
19337
|
const longRequiresCalibratedExpansion = direction === "LONG" && !calibratedExpansionPocket;
|
|
19225
|
-
const
|
|
19338
|
+
const longDirectIndicatorSupportMissing = longDirectIndicatorSupportConfirmed === false;
|
|
19339
|
+
const approvalDisqualifiedByCalibration = !calibratedExpansionPocket && (longRequiresCalibratedExpansion || isContinuationBreakoutRetest || hasOverextendedVolumeConfirmation || hasIsolatedIndicatorSupport) || ethReferenceWeakNonStressPocket || longDirectIndicatorSupportMissing;
|
|
19226
19340
|
if (longRequiresCalibratedExpansion) {
|
|
19227
19341
|
softBlockReasons.push("long_liquidity_retest_requires_recalibration");
|
|
19228
19342
|
}
|
|
@@ -19235,6 +19349,12 @@ var buildLiquidityZonesGuardrailContext = ({
|
|
|
19235
19349
|
if (hasIsolatedIndicatorSupport) {
|
|
19236
19350
|
softBlockReasons.push("isolated_indicator_support");
|
|
19237
19351
|
}
|
|
19352
|
+
if (ethReferenceWeakNonStressPocket) {
|
|
19353
|
+
softBlockReasons.push("eth_reference_oi_weak_without_stress");
|
|
19354
|
+
}
|
|
19355
|
+
if (longDirectIndicatorSupportMissing) {
|
|
19356
|
+
softBlockReasons.push("long_direct_indicator_support_missing");
|
|
19357
|
+
}
|
|
19238
19358
|
const hasLongBreakoutConfirmation = direction === "LONG" && (breakoutState === "below_low_level" || breakoutState === "above_high_level") && reactionCloseDistancePct >= 1 && volumeRel20 != null && volumeRel20 >= 2 && venueSpreadZScore != null && venueSpreadZScore >= 0;
|
|
19239
19359
|
const hasShortContinuationConfirmation = direction === "SHORT" && hasVolumeConfirmation;
|
|
19240
19360
|
let deterministicQuality = 3;
|
|
@@ -19301,6 +19421,8 @@ var buildLiquidityZonesGuardrailContext = ({
|
|
|
19301
19421
|
transitionStructureExpansionPocket,
|
|
19302
19422
|
ethReferenceStressPocket,
|
|
19303
19423
|
solReferenceStressPocket,
|
|
19424
|
+
ethReferenceWeakNonStressPocket,
|
|
19425
|
+
longDirectIndicatorSupportConfirmed,
|
|
19304
19426
|
hardBlockReasons,
|
|
19305
19427
|
softBlockReasons,
|
|
19306
19428
|
deterministicQuality,
|
|
@@ -19394,6 +19516,7 @@ Additional Liquidity Zones context:
|
|
|
19394
19516
|
- obvLevelAligned=${String(context.obvLevelAligned ?? "n/a")}
|
|
19395
19517
|
- obvSlopeAligned=${String(context.obvSlopeAligned ?? "n/a")}
|
|
19396
19518
|
- directIndicatorSupportCount=${String(context.directIndicatorSupportCount ?? "n/a")}
|
|
19519
|
+
- longDirectIndicatorSupportConfirmed=${String(context.longDirectIndicatorSupportConfirmed ?? "n/a")}
|
|
19397
19520
|
- venueSpreadZScore=${String(context.venueSpreadZScore ?? "n/a")}
|
|
19398
19521
|
- benchmarkTrendAlignment=${context.benchmarkTrendAlignment ?? "n/a"}
|
|
19399
19522
|
- btcCorrelation=${String(context.btcCorrelation ?? "n/a")}
|
|
@@ -19412,6 +19535,7 @@ Additional Liquidity Zones context:
|
|
|
19412
19535
|
- transitionStructureExpansionPocket=${String(context.transitionStructureExpansionPocket)}
|
|
19413
19536
|
- ethReferenceStressPocket=${String(context.ethReferenceStressPocket)}
|
|
19414
19537
|
- solReferenceStressPocket=${String(context.solReferenceStressPocket)}
|
|
19538
|
+
- ethReferenceWeakNonStressPocket=${String(context.ethReferenceWeakNonStressPocket)}
|
|
19415
19539
|
- deterministicQuality=${context.deterministicQuality}
|
|
19416
19540
|
- approvalAllowedNow=${String(context.approvalAllowedNow)}
|
|
19417
19541
|
- hardBlockReasons=${JSON.stringify(context.hardBlockReasons)}
|
|
@@ -19427,6 +19551,8 @@ Interpretation rules for Liquidity Zones:
|
|
|
19427
19551
|
- Top-level derivatives context is BTC benchmark evidence; target-symbol derivatives require targetContext/targetDerived.
|
|
19428
19552
|
- Do not treat derivatives points, rows, or loaded-history size as approval evidence.
|
|
19429
19553
|
- A calibrated transition-structure pocket, ETH reference stress pocket, or SOL reference stress pocket can approve a structurally valid retest.
|
|
19554
|
+
- LONG approvals need at least two direct MA/MACD/OBV alignments after calibration.
|
|
19555
|
+
- Moderate ETH reference OI weakness blocks approval unless the deeper ETH reference stress pocket is active.
|
|
19430
19556
|
- Treat deterministicQuality and approvalAllowedNow as the local normalized gate result.
|
|
19431
19557
|
`.trim();
|
|
19432
19558
|
},
|
|
@@ -19892,6 +20018,16 @@ var getNestedString2 = (value, path) => {
|
|
|
19892
20018
|
}
|
|
19893
20019
|
return typeof current === "string" ? current : null;
|
|
19894
20020
|
};
|
|
20021
|
+
var getNestedBoolean2 = (value, path) => {
|
|
20022
|
+
let current = value;
|
|
20023
|
+
for (const segment of path) {
|
|
20024
|
+
if (!isRecord2(current)) {
|
|
20025
|
+
return null;
|
|
20026
|
+
}
|
|
20027
|
+
current = current[segment];
|
|
20028
|
+
}
|
|
20029
|
+
return typeof current === "boolean" ? current : null;
|
|
20030
|
+
};
|
|
19895
20031
|
var isShortBtcOnlyRecoveryLane = (context, baseContext) => {
|
|
19896
20032
|
const riskFlags = getNestedRecord2(baseContext, [
|
|
19897
20033
|
"derivatives",
|
|
@@ -19916,23 +20052,59 @@ var isShortBtcOnlyRecoveryLane = (context, baseContext) => {
|
|
|
19916
20052
|
const biasConflictState = getReverseTrendlineBiasConflictState(context);
|
|
19917
20053
|
return context.signalDirection === "SHORT" && context.entryTiming === "ready_rejection" && biasConflictState === "btc_only" && context.deterministicRejectionScore != null && context.deterministicRejectionScore >= 6 && context.distance != null && context.distance >= 61 && !hasMissingDerivatives && (derivativesPressure === "long_flush" || derivativesPressure === "short_flush" || derivativesPressure === "crowded_long") && volumeRel20 != null && volumeRel20 >= 1.5 && rangePosition20 != null && rangePosition20 >= 0.2 && rangePosition20 <= 0.7;
|
|
19918
20054
|
};
|
|
20055
|
+
var hasMissingDerivativesRisk = (baseContext) => {
|
|
20056
|
+
const riskFlags = getNestedRecord2(baseContext, [
|
|
20057
|
+
"derivatives",
|
|
20058
|
+
"summary"
|
|
20059
|
+
])?.riskFlags;
|
|
20060
|
+
return Array.isArray(riskFlags) && riskFlags.includes("missing_derivatives");
|
|
20061
|
+
};
|
|
20062
|
+
var isExtremeVolatilityRecoveryLane = (context, baseContext) => {
|
|
20063
|
+
if (context.hardBlockReasons.length > 0) {
|
|
20064
|
+
return false;
|
|
20065
|
+
}
|
|
20066
|
+
const primaryIssue = getNestedString2(baseContext, [
|
|
20067
|
+
"gateFeatures",
|
|
20068
|
+
"decisionHints",
|
|
20069
|
+
"primaryIssue"
|
|
20070
|
+
]);
|
|
20071
|
+
const approveBias = getNestedString2(baseContext, [
|
|
20072
|
+
"gateFeatures",
|
|
20073
|
+
"decisionHints",
|
|
20074
|
+
"approveBias"
|
|
20075
|
+
]);
|
|
20076
|
+
const upCloseStreak = getNestedNumber2(baseContext, [
|
|
20077
|
+
"regime",
|
|
20078
|
+
"momentum",
|
|
20079
|
+
"upCloseStreak"
|
|
20080
|
+
]);
|
|
20081
|
+
const adaptiveChannelFlipUp = getNestedBoolean2(baseContext, [
|
|
20082
|
+
"regime",
|
|
20083
|
+
"trend",
|
|
20084
|
+
"adaptiveChannel",
|
|
20085
|
+
"flipUp"
|
|
20086
|
+
]);
|
|
20087
|
+
const atrPctRank100 = getNestedNumber2(baseContext, [
|
|
20088
|
+
"regime",
|
|
20089
|
+
"volatility",
|
|
20090
|
+
"percentiles",
|
|
20091
|
+
"atrPctRank100"
|
|
20092
|
+
]);
|
|
20093
|
+
return primaryIssue === "extreme_volatility" && approveBias === "reject" && upCloseStreak != null && upCloseStreak <= 2 && adaptiveChannelFlipUp === false && atrPctRank100 != null && atrPctRank100 <= 99 && !hasMissingDerivativesRisk(baseContext);
|
|
20094
|
+
};
|
|
19919
20095
|
var getBaseContextQualityPromotion = (context, signal) => {
|
|
19920
20096
|
const baseContext = isRecord2(signal.additionalIndicators?.baseContext) ? signal.additionalIndicators.baseContext : null;
|
|
19921
20097
|
if (!baseContext) {
|
|
19922
20098
|
return null;
|
|
19923
20099
|
}
|
|
19924
|
-
return isShortBtcOnlyRecoveryLane(context, baseContext) ? 4 : null;
|
|
20100
|
+
return isShortBtcOnlyRecoveryLane(context, baseContext) || isExtremeVolatilityRecoveryLane(context, baseContext) ? 4 : null;
|
|
19925
20101
|
};
|
|
19926
20102
|
var getBaseContextApprovalBlockReasons = (context, signal) => {
|
|
19927
20103
|
const baseContext = isRecord2(signal.additionalIndicators?.baseContext) ? signal.additionalIndicators.baseContext : null;
|
|
19928
20104
|
if (!baseContext) {
|
|
19929
20105
|
return [];
|
|
19930
20106
|
}
|
|
19931
|
-
const
|
|
19932
|
-
"derivatives",
|
|
19933
|
-
"summary"
|
|
19934
|
-
])?.riskFlags;
|
|
19935
|
-
const hasMissingDerivatives = Array.isArray(riskFlags) && riskFlags.includes("missing_derivatives");
|
|
20107
|
+
const hasMissingDerivatives = hasMissingDerivativesRisk(baseContext);
|
|
19936
20108
|
const volumeRel20 = getNestedNumber2(baseContext, [
|
|
19937
20109
|
"participation",
|
|
19938
20110
|
"volume",
|
|
@@ -19968,6 +20140,10 @@ var getBaseContextApprovalBlockReasons = (context, signal) => {
|
|
|
19968
20140
|
context,
|
|
19969
20141
|
baseContext
|
|
19970
20142
|
);
|
|
20143
|
+
const extremeVolatilityRecoveryLane = isExtremeVolatilityRecoveryLane(
|
|
20144
|
+
context,
|
|
20145
|
+
baseContext
|
|
20146
|
+
);
|
|
19971
20147
|
const reasons = [];
|
|
19972
20148
|
if (hasMissingDerivatives) {
|
|
19973
20149
|
reasons.push("missing_derivatives");
|
|
@@ -19987,7 +20163,7 @@ var getBaseContextApprovalBlockReasons = (context, signal) => {
|
|
|
19987
20163
|
if (context.signalDirection === "SHORT" && biasConflictState === "btc_only" && context.distance != null && context.distance <= 60) {
|
|
19988
20164
|
reasons.push("short_btc_conflict_too_shallow");
|
|
19989
20165
|
}
|
|
19990
|
-
if (context.signalDirection === "SHORT" && atrPctZScore != null && atrPctZScore >= 2 && !shortBtcOnlyRecoveryLane) {
|
|
20166
|
+
if (context.signalDirection === "SHORT" && atrPctZScore != null && atrPctZScore >= 2 && !shortBtcOnlyRecoveryLane && !extremeVolatilityRecoveryLane) {
|
|
19991
20167
|
reasons.push("short_extreme_volatility");
|
|
19992
20168
|
}
|
|
19993
20169
|
if (context.signalDirection === "SHORT" && rangePosition20 != null && rangePosition20 < 0.2) {
|
|
@@ -20008,7 +20184,9 @@ var buildReverseTrendLineGateFeatures = ({
|
|
|
20008
20184
|
context,
|
|
20009
20185
|
signal,
|
|
20010
20186
|
approvalBlockReasons,
|
|
20011
|
-
deterministicRejectionScore
|
|
20187
|
+
deterministicRejectionScore,
|
|
20188
|
+
approvalLane,
|
|
20189
|
+
extremeVolatilityRecoveryPocket
|
|
20012
20190
|
}) => {
|
|
20013
20191
|
const baseContext = isRecord2(signal.additionalIndicators?.baseContext) ? signal.additionalIndicators.baseContext : null;
|
|
20014
20192
|
const volumeRel20 = getNestedNumber2(baseContext, [
|
|
@@ -20042,6 +20220,8 @@ var buildReverseTrendLineGateFeatures = ({
|
|
|
20042
20220
|
volatilityState,
|
|
20043
20221
|
rangePositionState,
|
|
20044
20222
|
highQualityBouncePocket: context.deterministicQuality >= 4 && approvalBlockReasons.length === 0 && (bounceAcceptance === "rejection" || bounceAcceptance === "follow_through"),
|
|
20223
|
+
extremeVolatilityRecoveryPocket,
|
|
20224
|
+
approvalLane,
|
|
20045
20225
|
deterministicRejectionScore
|
|
20046
20226
|
};
|
|
20047
20227
|
};
|
|
@@ -20166,7 +20346,14 @@ var buildReverseTrendlineAiContext = (signal) => {
|
|
|
20166
20346
|
},
|
|
20167
20347
|
signal
|
|
20168
20348
|
);
|
|
20169
|
-
const
|
|
20349
|
+
const baseContext = isRecord2(signal.additionalIndicators?.baseContext) ? signal.additionalIndicators.baseContext : null;
|
|
20350
|
+
const extremeVolatilityRecoveryPocket = baseContext != null ? isExtremeVolatilityRecoveryLane(
|
|
20351
|
+
{
|
|
20352
|
+
hardBlockReasons
|
|
20353
|
+
},
|
|
20354
|
+
baseContext
|
|
20355
|
+
) : false;
|
|
20356
|
+
const baseReverseTrendLineGateFeatures = buildReverseTrendLineGateFeatures({
|
|
20170
20357
|
context: {
|
|
20171
20358
|
...structural,
|
|
20172
20359
|
...timing,
|
|
@@ -20175,17 +20362,28 @@ var buildReverseTrendlineAiContext = (signal) => {
|
|
|
20175
20362
|
},
|
|
20176
20363
|
signal,
|
|
20177
20364
|
approvalBlockReasons,
|
|
20178
|
-
deterministicRejectionScore
|
|
20365
|
+
deterministicRejectionScore,
|
|
20366
|
+
approvalLane: "watch",
|
|
20367
|
+
extremeVolatilityRecoveryPocket
|
|
20179
20368
|
});
|
|
20369
|
+
const highScoreBouncePocket = baseReverseTrendLineGateFeatures.highQualityBouncePocket && deterministicRejectionScore != null && deterministicRejectionScore >= 7;
|
|
20370
|
+
const approvalLane = highScoreBouncePocket ? "high_score_bounce" : extremeVolatilityRecoveryPocket ? "extreme_volatility_recovery" : "watch";
|
|
20371
|
+
const approvalAllowedNow = approvalLane !== "watch";
|
|
20372
|
+
const finalApprovalBlockReasons = !approvalAllowedNow && promotedDeterministicQuality >= 4 && approvalBlockReasons.length === 0 ? [...approvalBlockReasons, "rejection_score_below_gate"] : approvalBlockReasons;
|
|
20373
|
+
const finalDeterministicQuality = approvalAllowedNow ? Math.max(promotedDeterministicQuality, 4) : promotedDeterministicQuality;
|
|
20374
|
+
const reverseTrendLineGateFeatures = {
|
|
20375
|
+
...baseReverseTrendLineGateFeatures,
|
|
20376
|
+
approvalLane
|
|
20377
|
+
};
|
|
20180
20378
|
return {
|
|
20181
20379
|
...structural,
|
|
20182
20380
|
...timing,
|
|
20183
20381
|
reverseTrendLineGateFeatures,
|
|
20184
|
-
deterministicQuality:
|
|
20382
|
+
deterministicQuality: finalDeterministicQuality,
|
|
20185
20383
|
deterministicRejectionScore,
|
|
20186
|
-
approvalAllowedNow
|
|
20384
|
+
approvalAllowedNow,
|
|
20187
20385
|
hardBlockReasons,
|
|
20188
|
-
approvalBlockReasons
|
|
20386
|
+
approvalBlockReasons: finalApprovalBlockReasons
|
|
20189
20387
|
};
|
|
20190
20388
|
};
|
|
20191
20389
|
var withReverseTrendLineGateFeatures = ({
|
|
@@ -20230,6 +20428,8 @@ var getHardBlockReasonText2 = (reason) => {
|
|
|
20230
20428
|
return "LONG bounce distance sits in a weak mid-distance pocket";
|
|
20231
20429
|
case "short_follow_through_overrated":
|
|
20232
20430
|
return "SHORT follow-through bounce is not reliable enough for quality 5";
|
|
20431
|
+
case "rejection_score_below_gate":
|
|
20432
|
+
return "deterministic rejection score is below the current strict gate";
|
|
20233
20433
|
default:
|
|
20234
20434
|
return reason;
|
|
20235
20435
|
}
|
|
@@ -20314,6 +20514,8 @@ Additional ReverseTrendLine context:
|
|
|
20314
20514
|
- reverseTrendLineGateVolatilityState=${context.reverseTrendLineGateFeatures.volatilityState}
|
|
20315
20515
|
- reverseTrendLineGateRangePositionState=${context.reverseTrendLineGateFeatures.rangePositionState}
|
|
20316
20516
|
- reverseTrendLineGateHighQualityBouncePocket=${String(context.reverseTrendLineGateFeatures.highQualityBouncePocket)}
|
|
20517
|
+
- reverseTrendLineGateExtremeVolatilityRecoveryPocket=${String(context.reverseTrendLineGateFeatures.extremeVolatilityRecoveryPocket)}
|
|
20518
|
+
- reverseTrendLineGateApprovalLane=${context.reverseTrendLineGateFeatures.approvalLane}
|
|
20317
20519
|
- approvalAllowedNow=${context.approvalAllowedNow}
|
|
20318
20520
|
- hardBlockReasons=${context.hardBlockReasons.join(", ") || "none"}
|
|
20319
20521
|
- approvalBlockReasons=${context.approvalBlockReasons.join(", ") || "none"}
|
|
@@ -20731,6 +20933,7 @@ var buildTrendFollowGateFeatures = ({
|
|
|
20731
20933
|
const referenceDerivativesLossBlock = direction === "SHORT" && referenceXrp15mOpenInterest != null && referenceXrp15mOpenInterest >= TREND_FOLLOW_REF_LOSS_XRP_OI_MIN && referenceEthCrowdingPersistenceBars != null && referenceEthCrowdingPersistenceBars >= TREND_FOLLOW_REF_LOSS_ETH_CROWDING_MIN && referenceSol15mFundingZScore != null && referenceSol15mFundingZScore <= TREND_FOLLOW_REF_LOSS_SOL_FUNDING_Z_MAX;
|
|
20732
20934
|
const referenceDerivativesCadencePocket = !referenceDerivativesLossBlock && (legacyCadencePocket || referenceDerivativesOiCompressionPocket || referenceDerivativesXrpFundingPocket || referenceDerivativesSolFlushPocket);
|
|
20733
20935
|
const referenceDerivativesOpeningPocket = direction === "SHORT" && minutesFromSessionOpen != null && minutesFromSessionOpen <= TREND_FOLLOW_OPENING_SESSION_MAX_MINUTES_FROM_OPEN && referenceXrp15mOpenInterest != null && referenceXrp15mOpenInterest <= TREND_FOLLOW_OPENING_REF_XRP_OI_MAX && referenceXrp1hOiChangePct1h != null && referenceXrp1hOiChangePct1h >= TREND_FOLLOW_OPENING_REF_XRP_OI_CHANGE_1H_MIN && referenceBnb15mOpenInterest != null && referenceBnb15mOpenInterest >= TREND_FOLLOW_OPENING_REF_BNB_OI_MIN;
|
|
20936
|
+
const referenceDerivativesCleanCadencePocket = referenceDerivativesCadencePocket && !derivativesShortFlushOiPocket;
|
|
20734
20937
|
const normalVolatilityCadencePocket = marketVolatilityState === TREND_FOLLOW_ALLOWED_VOLATILITY_STATE;
|
|
20735
20938
|
return {
|
|
20736
20939
|
setupStopDistanceAtr,
|
|
@@ -20773,9 +20976,10 @@ var buildTrendFollowGateFeatures = ({
|
|
|
20773
20976
|
referenceDerivativesSolFlushPocket,
|
|
20774
20977
|
referenceDerivativesLossBlock,
|
|
20775
20978
|
referenceDerivativesCadencePocket,
|
|
20979
|
+
referenceDerivativesCleanCadencePocket,
|
|
20776
20980
|
referenceDerivativesOpeningPocket,
|
|
20777
20981
|
normalVolatilityCadencePocket,
|
|
20778
|
-
highQualityCadencePocket: normalVolatilityCadencePocket &&
|
|
20982
|
+
highQualityCadencePocket: normalVolatilityCadencePocket && referenceDerivativesCleanCadencePocket
|
|
20779
20983
|
};
|
|
20780
20984
|
};
|
|
20781
20985
|
var buildTrendFollowGuardrailContext = ({
|
|
@@ -21035,6 +21239,7 @@ Additional TrendFollow context:
|
|
|
21035
21239
|
- trendFollowGateReferenceDerivativesSolFlushPocket=${String(context.trendFollowGateFeatures.referenceDerivativesSolFlushPocket)}
|
|
21036
21240
|
- trendFollowGateReferenceDerivativesLossBlock=${String(context.trendFollowGateFeatures.referenceDerivativesLossBlock)}
|
|
21037
21241
|
- trendFollowGateReferenceDerivativesCadencePocket=${String(context.trendFollowGateFeatures.referenceDerivativesCadencePocket)}
|
|
21242
|
+
- trendFollowGateReferenceDerivativesCleanCadencePocket=${String(context.trendFollowGateFeatures.referenceDerivativesCleanCadencePocket)}
|
|
21038
21243
|
- trendFollowGateReferenceDerivativesOpeningPocket=${String(context.trendFollowGateFeatures.referenceDerivativesOpeningPocket)}
|
|
21039
21244
|
- trendFollowGateNormalVolatilityCadencePocket=${String(context.trendFollowGateFeatures.normalVolatilityCadencePocket)}
|
|
21040
21245
|
- trendFollowGateHighQualityCadencePocket=${String(context.trendFollowGateFeatures.highQualityCadencePocket)}
|
|
@@ -21054,7 +21259,7 @@ Interpretation rules for TrendFollow:
|
|
|
21054
21259
|
- The ATR trailing stop is the structural invalidation line and also updates while a position is open.
|
|
21055
21260
|
- Prefer breakouts aligned with shared market context and backed by participation.
|
|
21056
21261
|
- Late, thin, crowded, inside-range, adverse-delta, weak-momentum, or weak-volume-structure breakouts should be downgraded even if the pivot cross is valid.
|
|
21057
|
-
- Live approval is reserved for calibrated SHORT derivatives pockets in normal volatility
|
|
21262
|
+
- Live approval is reserved for calibrated SHORT extra-reference derivatives pockets in normal volatility when the BTC benchmark short-flush/OI pocket is not active; legacy BTC benchmark flush and opening-session recovery remain watch mode.
|
|
21058
21263
|
- Treat deterministicQuality and approvalAllowedNow as the local normalized gate result.
|
|
21059
21264
|
`.trim();
|
|
21060
21265
|
},
|
|
@@ -21091,6 +21296,8 @@ var LONG_BROAD_MARKET_SHORT_FLUSH_PCT_ABOVE_MA20_MIN = 0.95;
|
|
|
21091
21296
|
var LONG_BROAD_MARKET_SHORT_FLUSH_BTC_VS_ALT_RETURN_24H_MIN = 0;
|
|
21092
21297
|
var SHORT_ASIA_LONG_FLUSH_LOW_CMC_FEAR_GREED_MAX = 18;
|
|
21093
21298
|
var SHORT_ASIA_LONG_FLUSH_ADVANCERS_MAX = 2;
|
|
21299
|
+
var BNB_REFERENCE_OI_CHANGE_PCT_4H_RISK_MIN = 0;
|
|
21300
|
+
var DERIVATIVES_DATA_UNAVAILABLE_STRESS_CMC_FEAR_GREED_MAX = 25;
|
|
21094
21301
|
var toMtfAlignmentForTrendShift = ({
|
|
21095
21302
|
direction,
|
|
21096
21303
|
mtfAlignment
|
|
@@ -21358,9 +21565,14 @@ var buildTrendShiftGuardrailContext = ({
|
|
|
21358
21565
|
gateRelative?.cmcFearGreedValueChange24h ?? baseCmcFearGreed?.valueChange24h
|
|
21359
21566
|
);
|
|
21360
21567
|
const cmcFearGreedStale = gateRelative?.cmcFearGreedStale === true || baseCmcFearGreed?.stale === true;
|
|
21568
|
+
const derivativesDataUnavailable = derivativesRiskFlags.includes("missing_derivatives") || derivativesRiskFlags.includes("stale_derivatives");
|
|
21569
|
+
const derivativesDataUnavailableStressRisk = derivativesDataUnavailable && cmcFearGreedStale !== true && cmcFearGreedValue != null && cmcFearGreedValue <= DERIVATIVES_DATA_UNAVAILABLE_STRESS_CMC_FEAR_GREED_MAX;
|
|
21361
21570
|
const derivatives1hLiqShort = asFiniteNumber6(
|
|
21362
21571
|
baseContext?.derivatives?.intervals?.["1h"]?.liqShort
|
|
21363
21572
|
);
|
|
21573
|
+
const bnbReferenceOiChangePct4h = asFiniteNumber6(
|
|
21574
|
+
baseContext?.derivatives?.referenceContexts?.BNBUSDT?.intervals?.["1h"]?.oiChangePct4h
|
|
21575
|
+
);
|
|
21364
21576
|
const btcAltRegime = typeof gateRelative?.btcAltRegime === "string" ? gateRelative.btcAltRegime : null;
|
|
21365
21577
|
const btcAltRegimeStale = gateRelative?.btcAltRegimeStale === true;
|
|
21366
21578
|
const cmcExchangeLiquidityVolumeChange24hPct = asFiniteNumber6(
|
|
@@ -21385,8 +21597,8 @@ var buildTrendShiftGuardrailContext = ({
|
|
|
21385
21597
|
const q4LongBreakoutCandidate = signalContext.signalDirection === "LONG" && breakoutState === "above_high_level" && volumeRel20 != null && volumeRel20 >= 1.2 && atrPctZScore != null && atrPctZScore >= 0 && relativeStrength1h != null && relativeStrength1h > -1 && derivativesPressure === "short_flush";
|
|
21386
21598
|
const q4ShortBreakoutCandidate = signalContext.signalDirection === "SHORT" && breakoutState === "below_low_level" && volumeRel20 != null && volumeRel20 >= 1.2 && atrPctZScore != null && atrPctZScore >= 0 && relativeStrength1h != null && relativeStrength1h < 1 && derivativesPressure === "long_flush";
|
|
21387
21599
|
const q4ShortAsiaFlushCandidate = signalContext.signalDirection === "SHORT" && derivativesPressure === "neutral" && derivativesFlushSupport && sessionPrimary === "asia" && !sessionIsOverlap && distanceAtrRatio < 0.7 && slopeAbs >= 0.08 && closeVsAvgPctAbs >= 0.12;
|
|
21388
|
-
const selectiveNeutralQ4Candidate = hasDerivativesSummary && derivativesPressure === "neutral" && !sessionIsOverlap && (signalContext.signalDirection === "LONG" && sessionPrimary === "europe" && (breakoutState === "above_high_level" || breakoutState === "failed_high_breakout") || signalContext.signalDirection === "SHORT" && (sessionPrimary === "off_hours" || sessionPrimary === "asia") && breakoutState === "below_low_level");
|
|
21389
|
-
const shortNeutralBearChannelBreakdownCandidate = signalContext.signalDirection === "SHORT" && breakoutState === "below_low_level" && derivativesPressure === "neutral" && atrPctZScore != null && atrPctZScore >= 0 && atrPctZScore < 1 && adaptiveChannelDirection === "bear";
|
|
21600
|
+
const selectiveNeutralQ4Candidate = hasDerivativesSummary && derivativesPressure === "neutral" && !derivativesDataUnavailableStressRisk && !sessionIsOverlap && (signalContext.signalDirection === "LONG" && sessionPrimary === "europe" && (breakoutState === "above_high_level" || breakoutState === "failed_high_breakout") || signalContext.signalDirection === "SHORT" && (sessionPrimary === "off_hours" || sessionPrimary === "asia") && breakoutState === "below_low_level");
|
|
21601
|
+
const shortNeutralBearChannelBreakdownCandidate = signalContext.signalDirection === "SHORT" && breakoutState === "below_low_level" && derivativesPressure === "neutral" && !derivativesDataUnavailableStressRisk && atrPctZScore != null && atrPctZScore >= 0 && atrPctZScore < 1 && adaptiveChannelDirection === "bear";
|
|
21390
21602
|
let deterministicQuality = 3;
|
|
21391
21603
|
if (hardBlockReasons.length > 0) {
|
|
21392
21604
|
deterministicQuality = signalContext.confirmedFlip ? 2 : 1;
|
|
@@ -21454,6 +21666,10 @@ var buildTrendShiftGuardrailContext = ({
|
|
|
21454
21666
|
hardBlockReasons.push("us_short_oi_not_expanding");
|
|
21455
21667
|
}
|
|
21456
21668
|
}
|
|
21669
|
+
if (deterministicQuality >= 5 && derivativesDataUnavailableStressRisk) {
|
|
21670
|
+
deterministicQuality = 4;
|
|
21671
|
+
hardBlockReasons.push("derivatives_data_unavailable_stress");
|
|
21672
|
+
}
|
|
21457
21673
|
if (deterministicQuality >= 5 && hasDerivativesSummary && !selectiveNeutralQ4Candidate && !shortNeutralBearChannelBreakdownCandidate && derivativesPressure === "neutral" && !derivativesFlushSupport) {
|
|
21458
21674
|
deterministicQuality = 4;
|
|
21459
21675
|
hardBlockReasons.push("neutral_derivatives_pressure");
|
|
@@ -21476,6 +21692,7 @@ var buildTrendShiftGuardrailContext = ({
|
|
|
21476
21692
|
const shortAsiaLongFlushLowCmcBreadthRisk = signalContext.signalDirection === "SHORT" && sessionPrimary === "asia" && derivativesPressure === "long_flush" && cmcFearGreedStale !== true && marketBreadthStale !== true && cmcFearGreedValue != null && cmcFearGreedValue <= SHORT_ASIA_LONG_FLUSH_LOW_CMC_FEAR_GREED_MAX && marketBreadthAdvancers != null && marketBreadthAdvancers <= SHORT_ASIA_LONG_FLUSH_ADVANCERS_MAX;
|
|
21477
21693
|
const lowRewardToVolatilityRisk = rewardToVolatility != null && rewardToVolatility < 0.25;
|
|
21478
21694
|
const defensiveRewardToVolatilityRisk = rewardToVolatility != null && rewardToVolatility >= 0.25 && rewardToVolatility < 8;
|
|
21695
|
+
const bnbReferenceOiExpansionRisk = bnbReferenceOiChangePct4h != null && bnbReferenceOiChangePct4h >= BNB_REFERENCE_OI_CHANGE_PCT_4H_RISK_MIN;
|
|
21479
21696
|
const longBtcAltRegimeRisk = signalContext.signalDirection === "LONG" && btcAltRegimeStale !== true && (btcAltRegime === "btc_lead" || btcAltRegime === "risk_off");
|
|
21480
21697
|
const longBroadMarketShortFlushRisk = signalContext.signalDirection === "LONG" && derivativesPressure === "short_flush" && marketBreadthAdvancers != null && marketBreadthAdvancers >= LONG_BROAD_MARKET_SHORT_FLUSH_ADVANCERS_MIN && marketBreadthPctAboveMa20 != null && marketBreadthPctAboveMa20 >= LONG_BROAD_MARKET_SHORT_FLUSH_PCT_ABOVE_MA20_MIN && btcVsAltReturn24h != null && btcVsAltReturn24h >= LONG_BROAD_MARKET_SHORT_FLUSH_BTC_VS_ALT_RETURN_24H_MIN;
|
|
21481
21698
|
const cmcExchangeLiquidityVolumeChangeRisk = cmcExchangeLiquidityStale !== true && cmcExchangeLiquidityVolumeChange24hPct != null && (cmcExchangeLiquidityVolumeChange24hPct > -0.1 && cmcExchangeLiquidityVolumeChange24hPct < 0 || cmcExchangeLiquidityVolumeChange24hPct >= 0.1 && cmcExchangeLiquidityVolumeChange24hPct < 0.3);
|
|
@@ -21527,6 +21744,10 @@ var buildTrendShiftGuardrailContext = ({
|
|
|
21527
21744
|
deterministicQuality = 4;
|
|
21528
21745
|
hardBlockReasons.push("reward_to_volatility_below_defensive_threshold");
|
|
21529
21746
|
}
|
|
21747
|
+
if (deterministicQuality >= 5 && bnbReferenceOiExpansionRisk) {
|
|
21748
|
+
deterministicQuality = 4;
|
|
21749
|
+
hardBlockReasons.push("bnb_reference_1h_oi4h_expansion_risk");
|
|
21750
|
+
}
|
|
21530
21751
|
if (deterministicQuality >= 4 && longBtcAltRegimeRisk) {
|
|
21531
21752
|
deterministicQuality = 4;
|
|
21532
21753
|
hardBlockReasons.push("long_btc_alt_regime_risk");
|
|
@@ -21553,7 +21774,7 @@ var buildTrendShiftGuardrailContext = ({
|
|
|
21553
21774
|
const q4UsClosingOiConfirmationRecoveryCandidate = deterministicQuality === 4 && signalContext.confirmedFlip === true && signalContext.flipDistanceOk === true && sessionPrimary === "us" && sessionWindowPhase === "closing" && hardBlockReasons.length > 0 && hardBlockReasons.every(
|
|
21554
21775
|
(reason) => q4UsClosingOiConfirmationRecoveryAllowedReasons.includes(reason)
|
|
21555
21776
|
);
|
|
21556
|
-
const q4ShortBreadthShockLiquidationRecoveryCandidate = deterministicQuality === 4 && signalContext.signalDirection === "SHORT" && signalContext.confirmedFlip === true && signalContext.flipDistanceOk === true && marketBreadthReturn != null && marketBreadthReturn <= SHORT_BREADTH_SHOCK_MARKET_BREADTH_RETURN_MAX2 && derivatives1hLiqShort != null && derivatives1hLiqShort <= SHORT_BREADTH_SHOCK_1H_LIQ_SHORT_MAX;
|
|
21777
|
+
const q4ShortBreadthShockLiquidationRecoveryCandidate = deterministicQuality === 4 && signalContext.signalDirection === "SHORT" && signalContext.confirmedFlip === true && signalContext.flipDistanceOk === true && hardBlockReasons.length === 0 && !derivativesDataUnavailableStressRisk && marketBreadthReturn != null && marketBreadthReturn <= SHORT_BREADTH_SHOCK_MARKET_BREADTH_RETURN_MAX2 && derivatives1hLiqShort != null && derivatives1hLiqShort <= SHORT_BREADTH_SHOCK_1H_LIQ_SHORT_MAX;
|
|
21557
21778
|
const q4LongAltLeadershipRecoveryAllowedReasons = [
|
|
21558
21779
|
"flat_or_mixed_oi",
|
|
21559
21780
|
"neutral_derivatives_pressure",
|
|
@@ -21601,8 +21822,10 @@ var buildTrendShiftGuardrailContext = ({
|
|
|
21601
21822
|
shortBullSwingStructureRisk,
|
|
21602
21823
|
shortLowBollingerWidthRisk,
|
|
21603
21824
|
shortAsiaLongFlushLowCmcBreadthRisk,
|
|
21825
|
+
derivativesDataUnavailableStressRisk,
|
|
21604
21826
|
lowRewardToVolatilityRisk,
|
|
21605
21827
|
defensiveRewardToVolatilityRisk,
|
|
21828
|
+
bnbReferenceOiExpansionRisk,
|
|
21606
21829
|
longBtcAltRegimeRisk,
|
|
21607
21830
|
longBroadMarketShortFlushRisk,
|
|
21608
21831
|
cmcExchangeLiquidityVolumeChangeRisk,
|
|
@@ -21627,6 +21850,7 @@ var buildTrendShiftGuardrailContext = ({
|
|
|
21627
21850
|
cmcFearGreedValue,
|
|
21628
21851
|
cmcFearGreedValueChange24h,
|
|
21629
21852
|
derivatives1hLiqShort,
|
|
21853
|
+
bnbReferenceOiChangePct4h,
|
|
21630
21854
|
btcAltRegime,
|
|
21631
21855
|
cmcExchangeLiquidityVolumeChange24hPct,
|
|
21632
21856
|
trendShiftGateFeatures,
|
|
@@ -21694,10 +21918,14 @@ var getTrendShiftGuardrailReasonText = (reason) => {
|
|
|
21694
21918
|
return "the SHORT flip is in a narrow Bollinger-width compression pocket that has been less reliable, so keep it in watch mode";
|
|
21695
21919
|
case "short_asia_long_flush_low_cmc_breadth":
|
|
21696
21920
|
return "the SHORT flip is selling an Asia-session long flush while CMC fear/greed and market breadth are already in capitulation, so keep it in watch mode";
|
|
21921
|
+
case "derivatives_data_unavailable_stress":
|
|
21922
|
+
return "benchmark derivatives data is missing or stale during CMC stress, so keep the flip in watch mode instead of treating neutral derivatives as confirmation";
|
|
21697
21923
|
case "low_reward_to_volatility":
|
|
21698
21924
|
return "the expected reward is too small relative to current volatility after costs, so keep the flip in watch mode";
|
|
21699
21925
|
case "reward_to_volatility_below_defensive_threshold":
|
|
21700
21926
|
return "the expected reward is not large enough relative to current volatility for the defensive TrendShift gate after costs";
|
|
21927
|
+
case "bnb_reference_1h_oi4h_expansion_risk":
|
|
21928
|
+
return "BNB reference 1h open interest is expanding over 4h, a historically fragile cross-market state for TrendShift approvals";
|
|
21701
21929
|
case "long_btc_alt_regime_risk":
|
|
21702
21930
|
return "the LONG flip is fighting a BTC-led or risk-off alt regime, so keep it in watch mode";
|
|
21703
21931
|
case "long_broad_market_short_flush_risk":
|
|
@@ -21850,8 +22078,11 @@ Additional TrendShift context:
|
|
|
21850
22078
|
- defensiveRewardToVolatilityRisk=${String(context.defensiveRewardToVolatilityRisk)}
|
|
21851
22079
|
- shortBullSwingStructureRisk=${String(context.shortBullSwingStructureRisk)}
|
|
21852
22080
|
- shortAsiaLongFlushLowCmcBreadthRisk=${String(context.shortAsiaLongFlushLowCmcBreadthRisk)}
|
|
22081
|
+
- derivativesDataUnavailableStressRisk=${String(context.derivativesDataUnavailableStressRisk)}
|
|
21853
22082
|
- longBtcAltRegimeRisk=${String(context.longBtcAltRegimeRisk)}
|
|
21854
22083
|
- longBroadMarketShortFlushRisk=${String(context.longBroadMarketShortFlushRisk)}
|
|
22084
|
+
- bnbReferenceOiChangePct4h=${String(context.bnbReferenceOiChangePct4h ?? "n/a")}
|
|
22085
|
+
- bnbReferenceOiExpansionRisk=${String(context.bnbReferenceOiExpansionRisk)}
|
|
21855
22086
|
- cmcExchangeLiquidityVolumeChangeRisk=${String(context.cmcExchangeLiquidityVolumeChangeRisk)}
|
|
21856
22087
|
- q4TrendShiftGateFeaturesRecoveryCandidate=${String(context.q4TrendShiftGateFeaturesRecoveryCandidate)}
|
|
21857
22088
|
- q4UsClosingOiConfirmationRecoveryCandidate=${String(context.q4UsClosingOiConfirmationRecoveryCandidate)}
|
|
@@ -21889,12 +22120,14 @@ Interpretation rules for TrendShift:
|
|
|
21889
22120
|
- For SHORT, a bullish swing structure is a watch-only warning even when the immediate flip geometry looks q5-strong.
|
|
21890
22121
|
- For SHORT, a narrow Bollinger-width compression pocket is watch-only even if another q4 recovery condition is present.
|
|
21891
22122
|
- For SHORT, Asia-session long-flush setups are watch-only when CMC fear/greed and market breadth are already in capitulation.
|
|
22123
|
+
- If benchmark derivatives data is missing or stale while CMC fear/greed is in stress mode, keep the flip in watch mode; neutral/unknown derivatives are not confirmation in that state.
|
|
21892
22124
|
- The defensive live gate requires rewardToVolatility >= 8 when that field is available.
|
|
22125
|
+
- If BNB reference 1h open interest is expanding over the last 4h, keep TrendShift flips in watch mode; this is a defensive cross-market risk cut, not target-symbol evidence.
|
|
21893
22126
|
- For LONG, BTC-led or risk-off BTC/alt regime is watch-only even when flip geometry is q5-strong.
|
|
21894
22127
|
- For LONG, broad-market squeeze clusters are watch-only when breadth is already extreme, BTC is leading alts, and benchmark derivatives show a short flush.
|
|
21895
22128
|
- If CMC major-exchange liquidity 24h change is in the historically choppy bands (-0.1, 0) or [0.1, 0.3), keep the flip in watch mode.
|
|
21896
22129
|
- A narrow q4 recovery is allowed during the US closing window only when the sole blocker is missing OI expansion on an otherwise liquidation-supported US-session flush.
|
|
21897
|
-
- A narrow SHORT q4 recovery may pass during a market breadth shock only when marketBreadthReturn <= -0.0112952 and 1h liqShort <= 0.208; this does not override the low-Bollinger-width defensive cut.
|
|
22130
|
+
- A narrow SHORT q4 recovery may pass during a market breadth shock only when marketBreadthReturn <= -0.0112952 and 1h liqShort <= 0.208; this does not override existing hard blockers or the low-Bollinger-width defensive cut.
|
|
21898
22131
|
- A narrow LONG q4 recovery may pass only when alt leadership is clear (btcVsAltReturn24h <= -0.00503054 and btcVsAltReturn1h <= -0.00581403), fear/greed is not falling hard, and the only blockers are the tested OI/benchmark-derivatives or defensive reward-to-volatility blockers.
|
|
21899
22132
|
- If hardBlockReasons is not empty, explain exactly what is still missing for confirmation.
|
|
21900
22133
|
`.trim();
|
|
@@ -22210,6 +22443,9 @@ var TRENDLINE_PAYLOAD_PROMPT = `
|
|
|
22210
22443
|
- It also includes 'atrPct / breakVsAtrRatio / coinMaSpreadPct / btcMaSpreadPct / aggressivePreBreakPressure / strongNearBreakPressure / weakCleanBreak / compressedCleanBreak / weakBtcLedBreak / weakLongFarBreak'.
|
|
22211
22444
|
- If 'payload.additionalIndicators.baseContext.derivatives' exists, it contains Coinalyze-derived open interest, funding, and liquidation fields for the signal moment; do not treat 'stale' or 'missing_derivatives' as confirmation or conflict.
|
|
22212
22445
|
`;
|
|
22446
|
+
var MARKET_CONTEXT_PRIMARY_ISSUE = "market_context_against";
|
|
22447
|
+
var MARKET_CONTEXT_TOTAL_MARKET_CAP_USD_MIN = 233e10;
|
|
22448
|
+
var MARKET_CONTEXT_TREND_PERSISTENCE_MAX = 0.77;
|
|
22213
22449
|
var getRecord2 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
22214
22450
|
var getNestedRecord3 = (source, path) => {
|
|
22215
22451
|
let current = source;
|
|
@@ -22285,6 +22521,22 @@ var buildTrendlineContext = (signal) => {
|
|
|
22285
22521
|
const volumeStructurePocIndex = toFiniteNumberOrNull5(
|
|
22286
22522
|
participationVolumeStructure?.pocIndex
|
|
22287
22523
|
);
|
|
22524
|
+
const gateDecisionHints = getNestedRecord3(baseContext, [
|
|
22525
|
+
"gateFeatures",
|
|
22526
|
+
"decisionHints"
|
|
22527
|
+
]);
|
|
22528
|
+
const gatePrimaryIssue = typeof gateDecisionHints?.primaryIssue === "string" ? gateDecisionHints.primaryIssue : null;
|
|
22529
|
+
const cmcGlobalContext = getNestedRecord3(baseContext, [
|
|
22530
|
+
"relative",
|
|
22531
|
+
"cmcGlobal"
|
|
22532
|
+
]);
|
|
22533
|
+
const cmcTotalMarketCapUsd = toFiniteNumberOrNull5(
|
|
22534
|
+
cmcGlobalContext?.totalMarketCapUsd
|
|
22535
|
+
);
|
|
22536
|
+
const trendRegimeContext = getNestedRecord3(baseContext, ["regime", "trend"]);
|
|
22537
|
+
const trendPersistence = toFiniteNumberOrNull5(
|
|
22538
|
+
trendRegimeContext?.persistence
|
|
22539
|
+
);
|
|
22288
22540
|
const benchmarkTrendAlignment = typeof benchmarkContext?.trendAlignment === "string" ? benchmarkContext.trendAlignment : null;
|
|
22289
22541
|
const executionContext = getNestedRecord3(baseContext, [
|
|
22290
22542
|
"relative",
|
|
@@ -22336,7 +22588,7 @@ var buildTrendlineContext = (signal) => {
|
|
|
22336
22588
|
if (structural.signalDirection === "SHORT" && (entryTiming === "ready_follow_through" || entryTiming === "ready_retest") && (sessionPrimary === "off_hours" || sessionIsOverlap) && !hardBlockReasons.includes("short_session_risk")) {
|
|
22337
22589
|
hardBlockReasons.push("short_session_risk");
|
|
22338
22590
|
}
|
|
22339
|
-
const
|
|
22591
|
+
const baseDeterministicQuality = getDeterministicTrendlineQuality({
|
|
22340
22592
|
signalDirection: structural.signalDirection,
|
|
22341
22593
|
clearBreak: structural.clearBreak,
|
|
22342
22594
|
nearLineNoise: structural.nearLineNoise,
|
|
@@ -22351,16 +22603,18 @@ var buildTrendlineContext = (signal) => {
|
|
|
22351
22603
|
entryTiming,
|
|
22352
22604
|
coinMaSpreadPct
|
|
22353
22605
|
});
|
|
22606
|
+
const marketContextApprovalPocket = gatePrimaryIssue === MARKET_CONTEXT_PRIMARY_ISSUE && cmcTotalMarketCapUsd != null && cmcTotalMarketCapUsd >= MARKET_CONTEXT_TOTAL_MARKET_CAP_USD_MIN && trendPersistence != null && trendPersistence <= MARKET_CONTEXT_TREND_PERSISTENCE_MAX;
|
|
22607
|
+
const deterministicQuality = marketContextApprovalPocket ? 4 : baseDeterministicQuality;
|
|
22354
22608
|
const maxAllowedQuality = deterministicQuality;
|
|
22355
22609
|
const longUsLowVolumeCrowdedShortSqueeze = structural.signalDirection === "LONG" && sessionPrimary === "us" && volumeRel20 != null && volumeRel20 < 0.8 && derivativesRiskFlags.includes("crowded_short") && benchmarkTrendAlignment !== "against_benchmark";
|
|
22356
22610
|
const longHistoricalApprovalPocket = venueSpreadZScore != null && venueSpreadZScore <= -1 || longUsLowVolumeCrowdedShortSqueeze || sessionPrimary !== "europe" && !derivativesRiskFlags.includes("missing_derivatives") && !(structural.breakVsAtrRatio != null && structural.breakVsAtrRatio >= 0.8 && structural.breakVsAtrRatio < 1.2) && volumeRel20 != null && volumeRel20 >= 0.8 && benchmarkTrendAlignment !== "against_benchmark";
|
|
22357
|
-
const longHighQualitySessionApproval =
|
|
22611
|
+
const longHighQualitySessionApproval = baseDeterministicQuality >= 5 && sessionPrimary !== "asia";
|
|
22358
22612
|
const longStrongDerivativesAlignedApproval = volumeRel20 != null && volumeRel20 >= 1.5 && derivativesDirectionAligned === true;
|
|
22359
|
-
const longModerateRetestLiquidSessionApproval = structural.signalDirection === "LONG" &&
|
|
22613
|
+
const longModerateRetestLiquidSessionApproval = structural.signalDirection === "LONG" && baseDeterministicQuality === 4 && entryTiming === "ready_retest" && (sessionPrimary === "us" || sessionPrimary === "europe") && volumeRel20 != null && volumeRel20 >= 0.8 && volumeRel20 < 1.5 && benchmarkTrendAlignment !== "against_benchmark" && derivativesDirectionAligned == null && derivativesRiskFlags.length > 0 && !oiNotConfirming;
|
|
22360
22614
|
const longBaseContextApprovalPocket = structural.signalDirection !== "LONG" || longModerateRetestLiquidSessionApproval || longHistoricalApprovalPocket && (longHighQualitySessionApproval || longStrongDerivativesAlignedApproval);
|
|
22361
22615
|
const shortThinNeutralBenchmarkRisk = structural.signalDirection === "SHORT" && volumeRel20 != null && volumeRel20 < 0.8 && benchmarkTrendAlignment === "neutral";
|
|
22362
|
-
const q4ReferenceOiPocApproval =
|
|
22363
|
-
const approvalAllowedNow =
|
|
22616
|
+
const q4ReferenceOiPocApproval = baseDeterministicQuality === 4 && volumeStructurePocIndex != null && volumeStructurePocIndex >= 5 && ethReferenceOiAcceleration != null && ethReferenceOiAcceleration <= -0.5906;
|
|
22617
|
+
const approvalAllowedNow = marketContextApprovalPocket;
|
|
22364
22618
|
const trendLineGateFeatures = buildTrendLineGateFeatures({
|
|
22365
22619
|
structural,
|
|
22366
22620
|
entryTiming,
|
|
@@ -22396,6 +22650,11 @@ var buildTrendlineContext = (signal) => {
|
|
|
22396
22650
|
derivativesRiskFlags,
|
|
22397
22651
|
ethReferenceOiAcceleration,
|
|
22398
22652
|
oiNotConfirming,
|
|
22653
|
+
gatePrimaryIssue,
|
|
22654
|
+
cmcTotalMarketCapUsd,
|
|
22655
|
+
trendPersistence,
|
|
22656
|
+
marketContextApprovalPocket,
|
|
22657
|
+
baseDeterministicQuality,
|
|
22399
22658
|
longUsLowVolumeCrowdedShortSqueeze,
|
|
22400
22659
|
longHighQualitySessionApproval,
|
|
22401
22660
|
longStrongDerivativesAlignedApproval,
|
|
@@ -22645,6 +22904,11 @@ Additional TrendLine context:
|
|
|
22645
22904
|
- trendline.volumeStructurePocIndex=${formatPromptNumber(trendlineContext.volumeStructurePocIndex, 0)}
|
|
22646
22905
|
- trendline.ethReferenceOiAcceleration=${formatPromptNumber(trendlineContext.ethReferenceOiAcceleration, 3)}
|
|
22647
22906
|
- trendline.q4ReferenceOiPocApproval=${String(trendlineContext.q4ReferenceOiPocApproval)}
|
|
22907
|
+
- trendline.gatePrimaryIssue=${trendlineContext.gatePrimaryIssue ?? "n/a"}
|
|
22908
|
+
- trendline.cmcTotalMarketCapUsd=${formatPromptNumber(trendlineContext.cmcTotalMarketCapUsd, 0)}
|
|
22909
|
+
- trendline.trendPersistence=${formatPromptNumber(trendlineContext.trendPersistence, 3)}
|
|
22910
|
+
- trendline.marketContextApprovalPocket=${String(trendlineContext.marketContextApprovalPocket)}
|
|
22911
|
+
- trendline.baseDeterministicQuality=${String(trendlineContext.baseDeterministicQuality)}
|
|
22648
22912
|
- trendline.weakCleanBreak=${String(trendlineContext.weakCleanBreak)}
|
|
22649
22913
|
- trendline.compressedCleanBreak=${String(trendlineContext.compressedCleanBreak)}
|
|
22650
22914
|
- trendline.weakBtcLedBreak=${String(trendlineContext.weakBtcLedBreak)}
|
|
@@ -22923,10 +23187,13 @@ VolumeDivergence addon:
|
|
|
22923
23187
|
`;
|
|
22924
23188
|
var VOLUME_DIVERGENCE_PAYLOAD_PROMPT = `
|
|
22925
23189
|
- \`payload.additionalIndicators.volumeDivergenceContext\` contains a compact divergence-strength summary:
|
|
22926
|
-
divergenceKind / confirmationPrice / confirmationReady / structureAdvanced / reboundFromPivotPct / confirmationDistancePct / priceDisplacementPct / divergenceAmplitudeAtrRatio / reclaimPct / confirmationCandleQuality / volumeDivergenceStrength / deltaAligned / coinBiasAligned / btcBiasAligned / derivativesDirectionAligned / derivativesRiskFlags / derivativesLiqSpikeRatio / venueSpreadZScore / volumeRel20 / rangePosition20 / deterministicQuality / approvalAllowedNow / structuralHardBlockReasons / maxAllowedQuality.
|
|
23190
|
+
divergenceKind / confirmationPrice / confirmationReady / structureAdvanced / reboundFromPivotPct / confirmationDistancePct / priceDisplacementPct / divergenceAmplitudeAtrRatio / reclaimPct / confirmationCandleQuality / volumeDivergenceStrength / deltaAligned / coinBiasAligned / btcBiasAligned / derivativesDirectionAligned / derivativesRiskFlags / derivativesLiqSpikeRatio / venueSpreadZScore / volumeRel20 / rangePosition20 / btcOiChangePct1h15m / solOpenInterest15m / xrpFundingZScore15m / derivativesRegimePocket / deterministicQuality / approvalAllowedNow / structuralHardBlockReasons / maxAllowedQuality.
|
|
22927
23191
|
- Use this context as the explicit strategy-specific summary instead of trying to derive the same conclusion again only from generic candles.
|
|
22928
23192
|
- If \`payload.additionalIndicators.baseContext.derivatives\` exists, it is a Coinalyze-derived summary of derivatives state at signal time; \`stale\` or \`missing_derivatives\` means that Coinalyze context must not be used.
|
|
22929
23193
|
`;
|
|
23194
|
+
var BTC_OI_CHANGE_PCT_1H_15M_MAX = -0.32;
|
|
23195
|
+
var SOL_OPEN_INTEREST_15M_MIN = 101e5;
|
|
23196
|
+
var XRP_FUNDING_Z_SCORE_15M_MAX = -1.2;
|
|
22930
23197
|
var toFiniteNumberOrNull6 = (value) => {
|
|
22931
23198
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
22932
23199
|
return value;
|
|
@@ -23293,6 +23560,23 @@ var getVolumeDivergenceContext = (signal) => {
|
|
|
23293
23560
|
const derivativesRiskFlags = getStringArray3(derivativesSummary?.riskFlags);
|
|
23294
23561
|
const derivativesFundingZScore = toFiniteNumberOrNull6(derivatives15m?.fundingZScore) ?? toFiniteNumberOrNull6(derivatives1h?.fundingZScore);
|
|
23295
23562
|
const derivativesLiqSpikeRatio = toFiniteNumberOrNull6(derivatives15m?.liqSpikeRatio) ?? toFiniteNumberOrNull6(derivatives1h?.liqSpikeRatio);
|
|
23563
|
+
const btcOiChangePct1h15m = toFiniteNumberOrNull6(
|
|
23564
|
+
derivatives15m?.oiChangePct1h
|
|
23565
|
+
);
|
|
23566
|
+
const solOpenInterest15m = getNestedNumber3(derivativesContext, [
|
|
23567
|
+
"referenceContexts",
|
|
23568
|
+
"SOLUSDT",
|
|
23569
|
+
"intervals",
|
|
23570
|
+
"15m",
|
|
23571
|
+
"openInterest"
|
|
23572
|
+
]);
|
|
23573
|
+
const xrpFundingZScore15m = getNestedNumber3(derivativesContext, [
|
|
23574
|
+
"referenceContexts",
|
|
23575
|
+
"XRPUSDT",
|
|
23576
|
+
"intervals",
|
|
23577
|
+
"15m",
|
|
23578
|
+
"fundingZScore"
|
|
23579
|
+
]);
|
|
23296
23580
|
const marketContext = getRecord3(additional?.marketContext);
|
|
23297
23581
|
const venueSpreadZScore = getNestedNumber3(marketContext, [
|
|
23298
23582
|
"execution",
|
|
@@ -23392,9 +23676,9 @@ var getVolumeDivergenceContext = (signal) => {
|
|
|
23392
23676
|
entryThresholds,
|
|
23393
23677
|
aiThresholds
|
|
23394
23678
|
}) : hardBlockReasons.length > 0 ? 2 : 3;
|
|
23395
|
-
const
|
|
23396
|
-
const
|
|
23397
|
-
const approvalAllowedNow = hardBlockReasons.length === 0 &&
|
|
23679
|
+
const derivativesRegimePocket = isAtMost(btcOiChangePct1h15m, BTC_OI_CHANGE_PCT_1H_15M_MAX) && isAtLeast2(solOpenInterest15m, SOL_OPEN_INTEREST_15M_MIN) && isAtMost(xrpFundingZScore15m, XRP_FUNDING_Z_SCORE_15M_MAX);
|
|
23680
|
+
const maxAllowedQuality = derivativesRegimePocket ? Math.max(deterministicQuality, 4) : deterministicQuality;
|
|
23681
|
+
const approvalAllowedNow = hardBlockReasons.length === 0 && confirmationReady && derivativesRegimePocket && maxAllowedQuality >= 4;
|
|
23398
23682
|
return {
|
|
23399
23683
|
signalDirection,
|
|
23400
23684
|
divergenceKind,
|
|
@@ -23427,12 +23711,16 @@ var getVolumeDivergenceContext = (signal) => {
|
|
|
23427
23711
|
venueSpreadZScore,
|
|
23428
23712
|
volumeRel20,
|
|
23429
23713
|
rangePosition20,
|
|
23714
|
+
btcOiChangePct1h15m,
|
|
23715
|
+
solOpenInterest15m,
|
|
23716
|
+
xrpFundingZScore15m,
|
|
23717
|
+
derivativesRegimePocket,
|
|
23430
23718
|
sessionPhase,
|
|
23431
23719
|
hardBlockReasons,
|
|
23432
23720
|
structuralHardBlockReasons: [...hardBlockReasons],
|
|
23433
23721
|
deterministicQuality,
|
|
23434
23722
|
approvalAllowedNow,
|
|
23435
|
-
maxAllowedQuality
|
|
23723
|
+
maxAllowedQuality
|
|
23436
23724
|
};
|
|
23437
23725
|
};
|
|
23438
23726
|
var getVolumeDivergenceContextFromPayload = (payload, signal) => {
|
|
@@ -23483,6 +23771,7 @@ var postProcessAnalysis2 = ({
|
|
|
23483
23771
|
);
|
|
23484
23772
|
const needRetest = finalDirection == null;
|
|
23485
23773
|
const retestPrice = needRetest ? context.confirmationPrice : null;
|
|
23774
|
+
const approvedQuality = finalDirection != null && context.maxAllowedQuality >= 4 ? Math.max(finalQuality, 4) : finalQuality;
|
|
23486
23775
|
if (finalDirection == null) {
|
|
23487
23776
|
return {
|
|
23488
23777
|
...analysis,
|
|
@@ -23500,7 +23789,7 @@ var postProcessAnalysis2 = ({
|
|
|
23500
23789
|
return {
|
|
23501
23790
|
...analysis,
|
|
23502
23791
|
direction: finalDirection,
|
|
23503
|
-
quality:
|
|
23792
|
+
quality: approvedQuality,
|
|
23504
23793
|
needRetest,
|
|
23505
23794
|
retestPrice,
|
|
23506
23795
|
takeProfitPrice: signal.prices?.takeProfitPrice ?? null,
|
|
@@ -23546,6 +23835,10 @@ Additional VolumeDivergence context:
|
|
|
23546
23835
|
- venueSpreadZScore=${context.venueSpreadZScore?.toFixed?.(3) ?? "n/a"}
|
|
23547
23836
|
- volumeRel20=${context.volumeRel20?.toFixed?.(3) ?? "n/a"}
|
|
23548
23837
|
- rangePosition20=${context.rangePosition20?.toFixed?.(3) ?? "n/a"}
|
|
23838
|
+
- btcOiChangePct1h15m=${context.btcOiChangePct1h15m?.toFixed?.(3) ?? "n/a"}
|
|
23839
|
+
- solOpenInterest15m=${context.solOpenInterest15m?.toFixed?.(0) ?? "n/a"}
|
|
23840
|
+
- xrpFundingZScore15m=${context.xrpFundingZScore15m?.toFixed?.(3) ?? "n/a"}
|
|
23841
|
+
- derivativesRegimePocket=${context.derivativesRegimePocket}
|
|
23549
23842
|
- barsSincePivot=${context.barsSincePivot ?? "n/a"}
|
|
23550
23843
|
- barsBetweenPivotConfirmations=${context.barsBetweenPivotConfirmations ?? "n/a"}
|
|
23551
23844
|
- entryTiming=${context.entryTiming ?? "n/a"}
|