Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Long Description:
- // Buy/Sell SuperScript [reddit] is a unified master indicator that allows traders to monitor
- // reversal exhaustion (tops/bottoms), high-frequency continuation entries, and overnight gap
- // probabilities simultaneously. Every module is highly customizable and routed through a globally
- // unified trend-filtering engine (VIDYA Trend Engine) that supports both trend-aligned and
- // counter-trend (contra) filtering using normalized momentum slope thresholds
- // (Flat, Weak, Moderate, Strong). Additionally, all signals can be gated by a multi-timeframe
- // consensus. The script includes UI tables for TimeFrame consensus and a real-time
- // SPY/ES/SPX price conversion.
- //
- // TLDR Description: Unified master script combining Top, Bottom, HF, and Gap signals.
- // - top_finder & bottom_finder: Exhaustion reversals (weak/moderate/strong/momentum)
- // - hf_signals: High-frequency buy/sell continuation patterns
- // - overnight_gap: Statistical gap up/down probability and consensus tracking
- // - Global VIDYA Engine: Advanced trend-aligned & contra-trend slope filtering (Z-score normalized)
- // - Multi-TF consensus filtering capabilities for all underlying strategies
- // - On-chart tables for SPY/ES/SPX correlation math and Timeframe statuses
- // ─────────────────────────────────────────────────────────────────────────────
- //@version=6
- indicator("Buy/Sell SuperScript [reddit]", overlay=true, max_labels_count=500, max_lines_count=500, max_boxes_count=500)
- // === Input groups ===
- grpModules = "Modules"
- grpDisplaySignal = "Signal Display Settings"
- grpTopSignal = "top_finder - Signal"
- grpTopRegime = "top_finder - Regime Filters"
- grpTopTrend = "top_finder - Trend Filters"
- grpBottomSignal = "bottom_finder - Signal"
- grpBottomConfirm = "bottom_finder - Confirmation"
- grpBottomMomentum = "bottom_finder - Momentum"
- grpBottomTrend = "bottom_finder - Trend Filters"
- grpHfSignalsSignal = "hf_signals - Signal"
- grpHfSignalsNormalize = "hf_signals - Normalization"
- grpHfSignalsRegime = "hf_signals - Regime Filters"
- grpHfSignalsVolumeSqz = "hf_signals - Volume & Squeeze"
- grpDeltaVolumeCandles = "Delta Volume Candles"
- grpHfSignalsTrend = "hf_signals - Trend Filters"
- grpGap = "overnight_gap - Signal"
- grpGapTrend = "overnight_gap - Trend Filters"
- grpAlerts = "Alerts"
- grpColors = "Colors"
- grpVIDYA = "VIDYA Trend Engine"
- grpVIDYAAligned = "VIDYA Trend-Aligned Filters"
- grpVIDYAContra = "VIDYA Counter-Trend (Contra) Filters"
- grpTimeframes = "Timeframes"
- grpConverter = "SPY/ES/SPX Converter"
- // Webhook Configuration
- webhookKey = input.string("MY_SECRET_KEY", title="Secret Key", group=grpAlerts)
- alertExpiry = input.int(5, title="Alert Expiry (Minutes)", minval=1, group=grpAlerts)
- // === Global toggles ===
- useTop = input.bool(true, title="Enable top_finder Signals", group=grpModules)
- useBot = input.bool(true, title="Enable bottom_finder Signals", group=grpModules)
- useHfSignals = input.bool(true, title="Enable hf_signals (High Frequency) Signals", group=grpModules)
- useOvernightGap = input.bool(true, title="Enable Overnight Gap signals", group=grpModules)
- showConverter = input.bool(true, title="Show SPY / ES / SPX Converter Table", group=grpConverter)
- convPositionStr = input.string("Bottom Right", title="Table Position", options=["Top Right", "Bottom Right", "Bottom Left", "Top Left"], group=grpConverter)
- // === Signal Display Settings ===
- showTopStrong = input.bool(true, title="Show Top strong sell labels", group=grpDisplaySignal)
- showTopModerate = input.bool(true, title="Show Top moderate sell labels", group=grpDisplaySignal)
- showBottomWeak = input.bool(true, title="Show Bottom weak buy labels", group=grpDisplaySignal)
- showBottomModerate = input.bool(true, title="Show Bottom moderate buy labels", group=grpDisplaySignal)
- showBottomStrong = input.bool(true, title="Show Bottom strong buy labels", group=grpDisplaySignal)
- showMomentumBuy = input.bool(true, title="Show Momentum buy labels", group=grpDisplaySignal)
- showHfBuy = input.bool(true, title="Show hf_signals buy labels", group=grpDisplaySignal)
- showHfSell = input.bool(true, title="Show hf_signals sell labels", group=grpDisplaySignal)
- showOvernightGapBuy = input.bool(true, title="Show Overnight Gap buy labels", group=grpDisplaySignal)
- showOvernightGapSell = input.bool(true, title="Show Overnight Gap sell labels", group=grpDisplaySignal)
- // --------------------------------------------------
- // overnight_gap settings
- // --------------------------------------------------
- gapProbThreshold = input.int(75, title="High Prob Threshold (%)", minval=50, maxval=100, group=grpGap)
- gapConsensusReq = input.int(3, title="Required Momentum Consensus (1-4)", minval=1, maxval=4, group=grpGap)
- gapAnchorBars = input.int(3, title="Momentum Lookback Bars", minval=1, maxval=20, group=grpGap)
- gapFilterByTF = input.bool(false, title="Filter by Selected Timeframes", group=grpGapTrend)
- gapFilterByVIDYA = input.bool(false, title="Filter by VIDYA trend", group=grpGapTrend)
- gapFilterLogic = input.string("Normal", title="Trend Filter Logic", options=["Normal", "Contrarian"], group=grpGapTrend, tooltip="Normal: Buy = Bullish Trend, Sell = Bearish Trend.\nContrarian: Buy = Bearish Trend, Sell = Bullish Trend.")
- overnightGapAlertsEnabled = input.bool(true, title="Enable Overnight Gap alerts", group=grpAlerts)
- // --------------------------------------------------
- // top_finder settings
- // --------------------------------------------------
- topLen = input.int(150, title="Top length", group=grpTopSignal)
- topStrongAlertsEnabled = input.bool(true, title="Enable top strong sell alerts", group=grpAlerts)
- topModerateAlertsEnabled = input.bool(true, title="Enable top moderate sell alerts", group=grpAlerts)
- useTopCooldown = input.bool(true, title="Use cooldown", group=grpTopSignal)
- strongTopCooldownBars = input.int(5, title="Strong cooldown bars", minval=1, group=grpTopSignal)
- moderateTopCooldownBars = input.int(8, title="Moderate cooldown bars", minval=1, group=grpTopSignal)
- // Top regime filters
- useTopADX = input.bool(false, title="Use ADX filter", group=grpTopRegime)
- adxTopLen = input.int(16, title="ADX DI length", minval=5, group=grpTopRegime)
- adxTopSmooth = input.int(30, title="ADX smoothing", minval=5, group=grpTopRegime)
- adxTopMin = input.float(18.0, title="ADX min", step=0.5, group=grpTopRegime)
- useTopSlope = input.bool(false, title="Use slope filter", group=grpTopRegime)
- topSlopeLen = input.int(10, title="Slope lookback", minval=1, group=grpTopRegime)
- topMaLen = input.int(50, title="Slope MA length", minval=1, group=grpTopRegime)
- topAtrLen = input.int(14, title="ATR length", minval=1, group=grpTopRegime)
- slopeMinMultTop = input.float(0.20, title="Slope min multiplier", step=0.05, minval=0.0, group=grpTopRegime)
- useTopRSI = input.bool(true, title="Use RSI filter", group=grpTopRegime)
- topRSILen = input.int(6, title="RSI length", minval=1, group=grpTopRegime)
- topRSIThresh = input.int(70, title="RSI threshold", minval=50, maxval=100, group=grpTopRegime)
- topFilterByTF = input.bool(false, title="Filter sells by selected timeframes", group=grpTopTrend)
- topFilterByVIDYA = input.bool(false, title="Filter sells by VIDYA trend", group=grpTopTrend)
- topFilterLogic = input.string("Normal", title="Trend Filter Logic", options=["Normal", "Contrarian"], group=grpTopTrend, tooltip="Normal: Sells require Bearish trend.\nContrarian: Sells require Bullish trend.")
- // --------------------------------------------------
- // bottom_finder settings
- // --------------------------------------------------
- wvfPD = input.int(22, title="WVF Percentile LCD (pd)", group=grpBottomSignal)
- wvfBBL = input.int(20, title="WVF Bollinger band length", group=grpBottomSignal)
- wvfMult = input.float(2.0, minval=1.0, maxval=5.0, title="WVF Bollinger multiplier", group=grpBottomSignal)
- wvfLB = input.int(50, title="WVF lookback percentiles", group=grpBottomSignal)
- ph = input.float(0.85, title="WVF highest percentile coefficient", group=grpBottomSignal)
- pl = input.float(1.01, title="WVF lowest percentile coefficient", group=grpBottomSignal)
- weakThresh = input.float(0.98, title="WVF weak buy upper ratio threshold", minval=0, step=0.01, group=grpBottomSignal)
- moderateThresh = input.float(1.5, title="WVF moderate buy upper ratio threshold", minval=0, step=0.01, group=grpBottomSignal)
- bottomFirstOnly = input.bool(true, title="Indicate only first confirmed bar", group=grpBottomConfirm)
- botFilterByTF = input.bool(false, title="Filter buys by selected timeframes", group=grpBottomTrend)
- botFilterByVIDYA = input.bool(false, title="Filter buys by VIDYA trend", group=grpBottomTrend)
- botFilterLogic = input.string("Normal", title="Trend Filter Logic", options=["Normal", "Contrarian"], group=grpBottomTrend, tooltip="Normal: Buys require Bullish trend.\nContrarian: Buys require Bearish trend.")
- // The hf_signals family had separate bar-level cooldown, but here we rely on this for bottom sequential confirmation
- bottomWeakBars = input.int(6, title="Weak consecutive for confirm", minval=1, maxval=20, group=grpBottomConfirm)
- bottomModerateBars = input.int(4, title="Moderate consecutive for confirm", minval=1, maxval=20, group=grpBottomConfirm)
- bottomStrongBars = input.int(2, title="Strong consecutive for confirm", minval=1, maxval=20, group=grpBottomConfirm)
- weakAlertsEnabled = input.bool(true, title="Enable bottom weak buy alerts", group=grpAlerts)
- moderateAlertsEnabled = input.bool(true, title="Enable bottom moderate buy alerts", group=grpAlerts)
- strongAlertsEnabled = input.bool(true, title="Enable bottom strong buy alerts", group=grpAlerts)
- momentumAlertsEnabled = input.bool(true, title="Enable bottom momentum buy alerts", group=grpAlerts)
- // --------------------------------------------------
- // hf_signals settings
- // --------------------------------------------------
- hfSignalsSmaLen = input.int(9, title="SMA length", group=grpHfSignalsSignal)
- thresholdMode = input.string("Absolute", title="Threshold mode", options=["Absolute", "Percent", "ATR"], group=grpHfSignalsSignal)
- inchAbove = input.float(4.0, title="Threshold above SMA", group=grpHfSignalsSignal)
- inchBelow = input.float(4.0, title="Threshold below SMA", group=grpHfSignalsSignal)
- atrLen = input.int(4, title="ATR length", group=grpHfSignalsSignal)
- useCooldown = input.bool(true, title="Enable cooldown filters", group=grpHfSignalsSignal)
- maxBars = input.int(2, title="Max bars for pullback & resume", minval=1, group=grpHfSignalsSignal)
- minBarsBetween = input.int(7, title="Min bars between signals", minval=0, group=grpHfSignalsSignal)
- hfSignalsAutoNorm = input.bool(true, title="Universal auto-normalize", group=grpHfSignalsNormalize)
- normMode = input.string("ATR", title="Normalizer", options=["ATR", "Z-Score"], group=grpHfSignalsNormalize)
- normLookback = input.int(100, title="Z-score lookback", minval=20, group=grpHfSignalsNormalize)
- breakMult = input.float(0.60, title="Breakout multiple", minval=0.05, step=0.05, group=grpHfSignalsNormalize)
- bandMult = input.float(0.40, title="Pullback band multiple", minval=0.0, step=0.05, group=grpHfSignalsNormalize)
- roundToTick = input.bool(true, title="Round thresholds to mintick", group=grpHfSignalsNormalize)
- useNormFloor = input.bool(true, title="Apply minimum normalizer floor", group=grpHfSignalsNormalize)
- minNormTicks = input.int(20, title="Min normalizer (ticks)", minval=1, group=grpHfSignalsNormalize)
- useReclaimExtreme = input.bool(false, title="Require reclaim of breakout extreme", group=grpHfSignalsRegime)
- useADXFilter = input.bool(true, title="Filter ADX must be trending", group=grpHfSignalsRegime)
- diLen = input.int(16, title="DMI length", minval=5, group=grpHfSignalsRegime)
- adxSmoothing = input.int(30, title="ADX smoothing", minval=5, group=grpHfSignalsRegime)
- adxMin = input.float(15.0, title="ADX minimum", step=0.5, group=grpHfSignalsRegime)
- useHfSignalsSlopeFilter = input.bool(false, title="Slope filter", group=grpHfSignalsRegime)
- hfSignalsSlopeLen = input.int(10, title="Slope lookback", minval=1, group=grpHfSignalsRegime)
- hfSignalsSlopeMinMult = input.float(0.90, title="Min slope in norm units", step=0.05, minval=0.0, group=grpHfSignalsRegime)
- enforceAlternation = input.bool(true, title="Enforce alternating signals", group=grpHfSignalsRegime)
- hfBuyAlertsEnabled = input.bool(true, title="Enable HF buy alerts", group=grpAlerts)
- hfSellAlertsEnabled = input.bool(true, title="Enable HF sell alerts", group=grpAlerts)
- // Volume/squeeze filters (hf_signals)
- useVolFilter = input.bool(false, title="Volume confirmation", group=grpHfSignalsVolumeSqz)
- volLen = input.int(15, title="Volume SMA lookback", group=grpHfSignalsVolumeSqz)
- volMult = input.float(0.8, title="Volume multiplier", step=0.1, group=grpHfSignalsVolumeSqz)
- useDeltaVolumeLowerTF = input.bool(true, title="Use lower timeframe delta volume", group=grpHfSignalsVolumeSqz)
- deltaVolumeTF = input.timeframe("1", title="Delta Volume Lower TF", group=grpHfSignalsVolumeSqz)
- showDeltaVolumeCandles = input.bool(true, title="Show Delta Volume Candles", group=grpDeltaVolumeCandles)
- deltaVolumeDisplayOption = input.string("full bar", title="Delta Candle Display", options=["half bar", "full bar"], group=grpDeltaVolumeCandles)
- deltaVolUpColor = input.color(#089981, title="Delta Up color", group=grpDeltaVolumeCandles)
- deltaVolUpNegColor = input.color(#f23645, title="Delta Up - color", group=grpDeltaVolumeCandles)
- deltaVolDownColor = input.color(#f23645, title="Delta Down color", group=grpDeltaVolumeCandles)
- deltaVolDownPosColor = input.color(#089981, title="Delta Down + color", group=grpDeltaVolumeCandles)
- useSqzFilter = input.bool(true, title="Squeeze filter", group=grpHfSignalsVolumeSqz)
- sqzLen = input.int(100, title="Squeeze lookback", group=grpHfSignalsVolumeSqz)
- hfFilterByTF = input.bool(false, title="Filter by selected timeframes", group=grpHfSignalsTrend)
- hfFilterByVIDYA = input.bool(true, title="Filter by VIDYA trend", group=grpHfSignalsTrend)
- hfFilterLogic = input.string("Normal", title="Trend Filter Logic", options=["Normal", "Contrarian"], group=grpHfSignalsTrend, tooltip="Normal: Buy = Bullish Trend, Sell = Bearish Trend.\nContrarian: Buy = Bearish Trend, Sell = Bullish Trend.")
- // Colour options
- topStrongLabelColor = input.color(color.new(color.red, 0), title="Top strong label color", group=grpColors)
- topStrongTextColor = input.color(color.white, title="Top strong text color", group=grpColors)
- topModerateLabelColor = input.color(color.new(color.yellow, 0), title="Top moderate label color", group=grpColors)
- topModerateTextColor = input.color(color.black, title="Top moderate text color", group=grpColors)
- bottomWeakLabelColor = input.color(color.new(color.red, 0), title="Bottom weak label color", group=grpColors)
- bottomWeakTextColor = input.color(color.black, title="Bottom weak text color", group=grpColors)
- bottomModerateLabelColor = input.color(color.new(color.yellow, 0), title="Bottom moderate label color", group=grpColors)
- bottomModerateTextColor = input.color(color.black, title="Bottom moderate text color", group=grpColors)
- bottomStrongLabelColor = input.color(color.new(color.green, 0), title="Bottom strong label color", group=grpColors)
- bottomStrongTextColor = input.color(color.black, title="Bottom strong text color", group=grpColors)
- momentumLabelColor = input.color(color.new(color.purple, 0), title="Momentum buy label color", group=grpColors)
- momentumTextColor = input.color(color.white, title="Momentum buy text color", group=grpColors)
- hfSignalsBuyLabelColor = input.color(color.new(color.gray, 0), title="hf_signals buy color", group=grpColors)
- hfSignalsSellLabelColor = input.color(color.new(color.gray, 0), title="hf_signals sell color", group=grpColors)
- hfSignalsBuyTextColor = input.color(color.green, title="hf_signals buy text color", group=grpColors)
- hfSignalsSellTextColor = input.color(color.red, title="hf_signals sell text color", group=grpColors)
- hfSignalsBullBarColor = input.color(color.new(color.lime, 0), title="hf_signals bullish bar color", group=grpColors)
- hfSignalsBearBarColor = input.color(color.new(color.red, 0), title="hf_signals bearish bar color", group=grpColors)
- // VIDYA trend settings
- sourceVIDYA = close
- vidya_length = input.int(10, title='VIDYA Length', minval=1, group=grpVIDYA)
- vidya_momentum = input.int(20, title='VIDYA Momentum', minval=1, group=grpVIDYA)
- band_distance = input.float(2, 'Distance factor for upper/lower bands', step=0.1, group=grpVIDYA)
- up_trend_color = input.color(#17dfad, '+', group=grpVIDYA, inline='c')
- down_trend_color = input.color(#dd326b, '-', group=grpVIDYA, inline='c')
- shadow = input.bool(true, 'Shadow', group=grpVIDYA, inline='c')
- showVIDYA = input.bool(true, 'Show VIDYA overlay', group=grpVIDYA)
- showVIDYA_SlopeHistogram = input.bool(false, 'Show VIDYA slope histogram (separate pane)', group=grpVIDYA)
- vidya_flat_cutoff = input.float(0.3, title='VIDYA Flat/Weak cutoff', step=0.05, minval=0.0, group=grpVIDYA)
- vidya_weak_cutoff = input.float(1.0, title='VIDYA Weak/Moderate cutoff', step=0.05, minval=0.0, group=grpVIDYA)
- vidya_moderate_cutoff = input.float(1.5, title='VIDYA Moderate/Strong cutoff', step=0.05, minval=0.0, group=grpVIDYA)
- allowAlignedFlat = input.bool(true, title="Allow Flat Slope", group=grpVIDYAAligned)
- allowAlignedWeak = input.bool(true, title="Allow Weak Slope", group=grpVIDYAAligned)
- allowAlignedModerate = input.bool(true, title="Allow Moderate Slope", group=grpVIDYAAligned)
- allowAlignedStrong = input.bool(false, title="Allow Strong Slope", group=grpVIDYAAligned)
- allowContraFlat = input.bool(true, title="Allow Flat Slope", group=grpVIDYAContra)
- allowContraWeak = input.bool(false, title="Allow Weak Slope", group=grpVIDYAContra)
- allowContraModerate = input.bool(false, title="Allow Moderate Slope", group=grpVIDYAContra)
- allowContraStrong = input.bool(false, title="Allow Strong Slope", group=grpVIDYAContra)
- var float vidya_up_trend_volume = 0.0
- var float vidya_down_trend_volume = 0.0
- var label vidya_delta_volume_label = na
- var label vidya_trend_star_label = na
- t1 = input.timeframe('5', 'Time frame 1', group=grpTimeframes)
- active_t1 = input.bool(true, 'Monitor Time frame 1', group=grpTimeframes)
- t2 = input.timeframe('15', 'Time frame 2', group=grpTimeframes)
- active_t2 = input.bool(true, 'Monitor Time frame 2', group=grpTimeframes)
- t3 = input.timeframe('60', 'Time frame 3', group=grpTimeframes)
- active_t3 = input.bool(true, 'Monitor Time frame 3', group=grpTimeframes)
- t4 = input.timeframe('240', 'Time frame 4', group=grpTimeframes)
- active_t4 = input.bool(true, 'Monitor Time frame 4', group=grpTimeframes)
- t5 = input.timeframe('1D', 'Time frame 5', group=grpTimeframes)
- active_t5 = input.bool(true, 'Monitor Time frame 5', group=grpTimeframes)
- showTfTable = input.bool(true, title="Show TimeFrame Consensus Table", group=grpTimeframes)
- tfPositionStr = input.string("Top Right", title="Table Position", options=["Top Right", "Bottom Right", "Bottom Left", "Top Left"], group=grpTimeframes)
- string tfTablePosStr = tfPositionStr == "Bottom Right" ? position.bottom_right : tfPositionStr == "Top Right" ? position.top_right : tfPositionStr == "Bottom Left" ? position.bottom_left : position.top_left
- var table statusTable = table.new(tfTablePosStr, 2, 6, border_width=1, frame_color=color.new(color.gray, 80), border_color=color.new(color.gray, 80), bgcolor=color.new(color.black, 90))
- round_mintick(x) =>
- roundToTick and not na(x) ? math.round(x / syminfo.mintick) * syminfo.mintick : x
- // === VIDYA helper functions ===
- vidya_calc(src, vidya_length, vidya_momentum) =>
- float momentum = ta.change(src)
- float sum_pos_momentum = math.sum(momentum >= 0 ? momentum : 0.0, vidya_momentum)
- float sum_neg_momentum = math.sum(momentum >= 0 ? 0.0 : -momentum, vidya_momentum)
- float abs_cmo = math.abs(100 * (sum_pos_momentum - sum_neg_momentum) / (sum_pos_momentum + sum_neg_momentum))
- float alpha = 2 / (vidya_length + 1)
- var float vidya_value = 0.0
- vidya_value := alpha * abs_cmo / 100 * src + (1 - alpha * abs_cmo / 100) * nz(vidya_value[1])
- ta.sma(vidya_value, 15)
- f_vidya_trend(src) =>
- float vidya_value = vidya_calc(src, vidya_length, vidya_momentum)
- float vidya_atr = ta.atr(200)
- float upper_band = vidya_value + vidya_atr * band_distance
- float lower_band = vidya_value - vidya_atr * band_distance
- var int vidya_state = 0
- if ta.crossover(src, upper_band)
- vidya_state := 1
- if ta.crossunder(src, lower_band)
- vidya_state := -1
- vidya_state
- // === top_finder logic ===
- top_lowest = ta.lowest(topLen)
- top_highest = ta.highest(topLen)
- rocTop = ta.roc(close, 8)
- rocTop := rocTop / ta.stdev(ta.roc(close, 8), 200)
- top_strong = useTop and high < top_highest and high[1] == top_highest[1] and rocTop[2] > 2 and top_lowest == top_lowest[5] and barstate.isconfirmed
- top_moderate = useTop and high < top_highest and high[1] == top_highest[1] and not top_strong and barstate.isconfirmed
- // Top regime filter computations
- [_, _, adxValTop] = ta.dmi(adxTopLen, adxTopSmooth)
- maTop = ta.sma(close, topMaLen)
- atrTop = ta.atr(topAtrLen)
- slopeAbsTop = math.abs(maTop - maTop[topSlopeLen])
- topTrendOK = not useTopADX or adxValTop >= adxTopMin
- topSlopeOK = not useTopSlope or slopeAbsTop >= slopeMinMultTop * (atrTop)
- topRSI = ta.rsi(close, topRSILen)
- topRSIOK = not useTopRSI or topRSI >= topRSIThresh
- topRegimeOK = topTrendOK and topSlopeOK and topRSIOK
- strongTopPrevBars = ta.barssince(top_strong[1])
- moderateTopPrevBars = ta.barssince(top_moderate[1])
- strongTopConfirmed = top_strong and topRegimeOK and (not useTopCooldown or na(strongTopPrevBars) or strongTopPrevBars >= strongTopCooldownBars)
- moderateTopConfirmed = top_moderate and topRegimeOK and (not useTopCooldown or na(moderateTopPrevBars) or moderateTopPrevBars >= moderateTopCooldownBars)
- // === bottom_finder logic ===
- wvf = ((ta.highest(close, wvfPD)-low)/ta.highest(close, wvfPD))*100
- sDev = wvfMult * ta.stdev(wvf, wvfBBL)
- midLine = ta.sma(wvf, wvfBBL)
- upperBand = midLine + sDev
- rangeHigh = ta.highest(wvf, wvfLB) * ph
- signal = 0
- if wvf >= upperBand or wvf >= rangeHigh
- signal := wvf < weakThresh ? 1 : wvf < moderateThresh ? 2 : 3
- var int weakConsec = 0
- var int moderateConsec = 0
- var int strongConsec = 0
- if signal == 1
- weakConsec := nz(weakConsec[1],0)+1
- moderateConsec := 0
- strongConsec := 0
- else if signal == 2
- moderateConsec := nz(moderateConsec[1],0)+1
- weakConsec := 0
- strongConsec := 0
- else if signal == 3
- strongConsec := nz(strongConsec[1],0)+1
- weakConsec := 0
- moderateConsec := 0
- else
- weakConsec := 0
- moderateConsec := 0
- strongConsec := 0
- weakConfirmed = weakConsec >= bottomWeakBars
- moderateConfirmed = moderateConsec >= bottomModerateBars
- strongConfirmed= strongConsec >= bottomStrongBars
- weakFirst = weakConfirmed and weakConsec == bottomWeakBars
- moderateFirst = moderateConfirmed and moderateConsec == bottomModerateBars
- strongFirst = strongConfirmed and strongConsec == bottomStrongBars
- bottomConfirmed = weakConfirmed or moderateConfirmed or strongConfirmed
- bottomWasConfirmed = barstate.isfirst ? false : bottomConfirmed[1]
- bottomSignal = bottomFirstOnly ? (bottomConfirmed and not bottomWasConfirmed) : bottomConfirmed
- bottomWeakSignal = bottomFirstOnly ? weakFirst : weakConfirmed
- bottomModerateSignal = bottomFirstOnly ? moderateFirst : moderateConfirmed
- bottomStrongSignal = bottomFirstOnly ? strongFirst : strongConfirmed
- bottomSignalVisible = (showBottomWeak and bottomWeakSignal) or (showBottomModerate and bottomModerateSignal) or (showBottomStrong and bottomStrongSignal)
- momentumLowest = ta.lowest(150)
- momentumRoc = ta.roc(close, 8)
- momentumRoc := momentumRoc / ta.stdev(ta.roc(close, 8), 200)
- momentumBuyBase = low[1] == momentumLowest[1] and low > momentumLowest and low[2] == momentumLowest[2] and momentumRoc[2] < -2 and barstate.isconfirmed
- momentumBuySignal = showMomentumBuy and momentumBuyBase
- bottomLongColor = bottomStrongLabelColor
- bottomTextColor = bottomStrongTextColor
- if bottomFirstOnly
- if weakFirst
- bottomLongColor := bottomWeakLabelColor
- bottomTextColor := bottomWeakTextColor
- else if moderateFirst
- bottomLongColor := bottomModerateLabelColor
- bottomTextColor := bottomModerateTextColor
- else if strongFirst
- bottomLongColor := bottomStrongLabelColor
- bottomTextColor := bottomStrongTextColor
- else
- if weakConfirmed
- bottomLongColor := bottomWeakLabelColor
- bottomTextColor := bottomWeakTextColor
- else if moderateConfirmed
- bottomLongColor := bottomModerateLabelColor
- bottomTextColor := bottomModerateTextColor
- else if strongConfirmed
- bottomLongColor := bottomStrongLabelColor
- bottomTextColor := bottomStrongTextColor
- // === hf_signals logic ===
- smaHfSignals = ta.sma(close, hfSignalsSmaLen)
- atrHfSignals = ta.atr(atrLen)
- normUnit0 = normMode == "ATR" ? atrHfSignals : math.max(ta.stdev(close - smaHfSignals, normLookback), syminfo.mintick*2)
- normUnit = useNormFloor ? math.max(normUnit0, minNormTicks*syminfo.mintick) : normUnit0
- effThrAboveB = hfSignalsAutoNorm ? breakMult * normUnit : (thresholdMode=="Absolute"?inchAbove:(thresholdMode=="Percent"?smaHfSignals*inchAbove/100:atrHfSignals*inchAbove))
- effThrBelowB = hfSignalsAutoNorm ? breakMult * normUnit : (thresholdMode=="Absolute"?inchBelow:(thresholdMode=="Percent"?smaHfSignals*inchBelow/100:atrHfSignals*inchBelow))
- effPbBandB = hfSignalsAutoNorm ? bandMult * normUnit : 0.25
- effThrAboveB := round_mintick(effThrAboveB)
- effThrBelowB := round_mintick(effThrBelowB)
- effPbBandB := round_mintick(effPbBandB)
- // --- Dynamic Volume Logic for SPX because SPX has no volume---
- // Check if the current ticker is SPX (handles various exchange prefixes)
- isSPX = (syminfo.ticker == "SPX" or syminfo.root == "SPX")
- // Fetch SPY volume as a proxy ONLY if we are on SPX
- spyVolProxy = request.security("AMEX:SPY", timeframe.period, volume, gaps=barmerge.gaps_off)
- // Determine which volume to use: SPY volume for SPX charts, or native volume for everything else
- effectiveVol = isSPX ? spyVolProxy : volume
- deltaVolumeTicker = isSPX ? "AMEX:SPY" : syminfo.tickerid
- deltaVolTFsec = timeframe.in_seconds(deltaVolumeTF)
- chartTFsec = timeframe.in_seconds(timeframe.period)
- lowerTFAllowed = useDeltaVolumeLowerTF and deltaVolTFsec > 0 and deltaVolTFsec < chartTFsec
- float bullVol = na
- float bearVol = na
- if lowerTFAllowed
- [bV, sV, nV, tV, aCl] = request.security_lower_tf(deltaVolumeTicker, deltaVolumeTF, [close > open ? volume : 0, close < open ? volume : 0, close == open ? volume : 0, volume, close])
- bullVol := nz(bV.sum(), 0)
- bearVol := nz(sV.sum(), 0)
- else
- bullVol := close > open ? effectiveVol : 0
- bearVol := close < open ? effectiveVol : 0
- // --- HF Signals Volume Filter ---
- [_, _, adxValue] = ta.dmi(diLen, adxSmoothing)
- avgVolB = ta.sma(effectiveVol, volLen)
- // The filter now uses 'effectiveVol' (SPY for SPX, Native for others)
- volOK = not useVolFilter or effectiveVol > (avgVolB * volMult)
- basisB = ta.sma(close, sqzLen)
- devB = 2*ta.stdev(close, sqzLen)
- upperBB = basisB + devB
- lowerBB = basisB - devB
- atrSqz = ta.atr(sqzLen)
- upperKC = basisB + 1.5*atrSqz
- lowerKC = basisB - 1.5*atrSqz
- isSqueezed = lowerBB > lowerKC and upperBB < upperKC
- squeezeOK = not useSqzFilter or not isSqueezed
- hfSignalsSlopeMA = ta.sma(close, hfSignalsSlopeLen)
- hfSignalsSlopeAbs = math.abs(hfSignalsSlopeMA - hfSignalsSlopeMA[hfSignalsSlopeLen])
- hfSignalsSlopeOK = not useHfSignalsSlopeFilter or hfSignalsSlopeAbs >= hfSignalsSlopeMinMult * normUnit
- var int lastSignal = 0
- var int hfSignalsBarTrendState = 0
- var bool inBuy=false, pulledBuy=false, firedB=false
- var int startB = na
- var int lastBuyBar = na
- var float hiB=na
- var bool inSell=false, pulledSell=false, firedS=false
- var int startS = na
- var int lastSellBar = na
- var float loS=na
- if close < smaHfSignals
- inBuy := false
- pulledBuy := false
- firedB := false
- if not inBuy and (not useADXFilter or adxValue >= adxMin) and close > smaHfSignals + effThrAboveB
- inBuy := true
- pulledBuy := false
- firedB := false
- startB := bar_index
- hiB := high
- if inBuy
- hiB := math.max(hiB, high)
- if useCooldown and bar_index - startB > maxBars
- inBuy := false
- buyPulled = inBuy and not pulledBuy and low <= smaHfSignals + effPbBandB and close > smaHfSignals
- if buyPulled
- pulledBuy := true
- buySignalRawB = inBuy and pulledBuy and not firedB and close > smaHfSignals and close > open and (not useReclaimExtreme or close > hiB[1]) and (not useCooldown or bar_index - startB <= maxBars) and (na(lastBuyBar) or not useCooldown or bar_index - lastBuyBar >= minBarsBetween)
- buySignalB = buySignalRawB and (not enforceAlternation or lastSignal <= 0) and barstate.isconfirmed and volOK and squeezeOK and hfSignalsSlopeOK
- if buySignalB
- firedB := true
- lastBuyBar := bar_index
- lastSignal := 1
- hfSignalsBarTrendState := 1
- if close > smaHfSignals
- inSell := false
- pulledSell := false
- firedS := false
- if not inSell and (not useADXFilter or adxValue >= adxMin) and close < smaHfSignals - effThrBelowB
- inSell := true
- pulledSell := false
- firedS := false
- startS := bar_index
- loS := low
- if inSell
- loS := math.min(loS, low)
- if useCooldown and bar_index - startS > maxBars
- inSell := false
- sellPulled = inSell and not pulledSell and high >= smaHfSignals - effPbBandB and close < smaHfSignals
- if sellPulled
- pulledSell := true
- sellSignalRawB = inSell and pulledSell and not firedS and close < smaHfSignals and close < open and (not useReclaimExtreme or close < loS[1]) and (not useCooldown or bar_index - startS <= maxBars) and (na(lastSellBar) or not useCooldown or bar_index - lastSellBar >= minBarsBetween)
- sellSignalB = sellSignalRawB and (not enforceAlternation or lastSignal >= 0) and barstate.isconfirmed and volOK and squeezeOK and hfSignalsSlopeOK
- if sellSignalB
- firedS := true
- lastSellBar := bar_index
- lastSignal := -1
- hfSignalsBarTrendState := -1
- // === Plotting ===
- // VIDYA overlay styling replacing chart bar styling
- float vidya_value = vidya_calc(sourceVIDYA, vidya_length, vidya_momentum)
- float vidya_atr = ta.atr(200)
- float upper_band = vidya_value + vidya_atr * band_distance
- float lower_band = vidya_value - vidya_atr * band_distance
- var bool is_vidya_up = false
- if ta.crossover(sourceVIDYA, upper_band)
- is_vidya_up := true
- if ta.crossunder(sourceVIDYA, lower_band)
- is_vidya_up := false
- float smoothed_value = na
- if is_vidya_up
- smoothed_value := lower_band
- else
- smoothed_value := upper_band
- if ta.change(is_vidya_up)
- smoothed_value := na
- vidya_up_trend_volume := 0.0
- vidya_down_trend_volume := 0.0
- float delta_vol = bullVol - bearVol
- float delta_val = (bullVol + bearVol) != 0 ? delta_vol / (bullVol + bearVol) * 100 : 0
- string delta_volume = str.tostring(delta_val, format.percent)
- string delta_volume_abs = str.tostring(delta_vol, format.volume)
- float delta_vol_sum = bullVol + bearVol
- float delta_norm = effectiveVol != 0 ? delta_vol / effectiveVol : 0
- float delta_aNorm = math.abs(delta_norm)
- bool delta_pos = delta_norm >= 0
- float delta_abs_price = math.abs(open - close)
- float delta_price_min = math.min(open, close)
- float delta_price_max = math.max(open, close)
- float delta_price_avg = (open + close) / 2
- float delta_base = deltaVolumeDisplayOption == "half bar" ? delta_price_avg : delta_pos ? delta_price_min : delta_price_max
- float delta_value = deltaVolumeDisplayOption == "half bar" ? delta_price_avg + delta_norm * delta_abs_price / 2 : delta_pos ? delta_price_min + delta_aNorm * delta_abs_price : delta_price_max - delta_aNorm * delta_abs_price
- color delta_css = close > open ? deltaVolUpColor : close < open ? deltaVolDownColor : chart.fg_color
- color delta_cssD = color.new(delta_norm > 0 ? close > open ? deltaVolUpColor : deltaVolDownPosColor : close < open ? deltaVolDownColor : deltaVolUpNegColor, 50)
- barcolor(showDeltaVolumeCandles ? color.new(color.white, 100) : na, title="Hide Native Candles")
- plotcandle(delta_base, delta_base, delta_value, delta_value, title="Delta Volume Body", color=delta_cssD, wickcolor=na, bordercolor=na, display= showDeltaVolumeCandles ? display.all - display.status_line : display.none)
- plotcandle(open, high, low, close, title="Delta Volume Candle", color=na, wickcolor=delta_css, bordercolor=delta_css, display= showDeltaVolumeCandles ? display.all - display.status_line : display.none)
- plot(bullVol, title="Delta Bull Vol", display= showDeltaVolumeCandles ? display.data_window : display.none)
- plot(bearVol, title="Delta Bear Vol", display= showDeltaVolumeCandles ? display.data_window : display.none)
- plot(delta_vol, title="Delta Volume", display= showDeltaVolumeCandles ? display.data_window : display.none)
- bool trend_cross_up = not is_vidya_up[1] and is_vidya_up
- bool trend_cross_down = not is_vidya_up and is_vidya_up[1]
- color vidya_trend_color = is_vidya_up ? up_trend_color : down_trend_color
- p1 = plot(showVIDYA ? smoothed_value : na, title="VIDYA Trend", color=vidya_trend_color, linewidth=2, style=plot.style_linebr)
- p2 = plot(showVIDYA ? hl2 : na, title="VIDYA Reference", display=display.none)
- fill(p1, p2, smoothed_value, hl2, color.new(vidya_trend_color, shadow ? 80 : 100), color.new(vidya_trend_color, 100))
- plotshape(trend_cross_up[1] ? smoothed_value[0] : na, title="Trend Up", style=shape.labelup, location=location.absolute, color=color.new(up_trend_color, 50), text="▲", textcolor=chart.fg_color)
- plotshape(trend_cross_down[1] ? smoothed_value[0] : na, title="Trend Down", style=shape.labeldown, location=location.absolute, color=color.new(down_trend_color, 50), text="▼", textcolor=chart.fg_color)
- if barstate.islast and not na(smoothed_value)
- if showDeltaVolumeCandles
- if not na(vidya_delta_volume_label)
- label.delete(vidya_delta_volume_label)
- vidya_delta_volume_label := label.new(bar_index, smoothed_value, 'Buy: ' + str.tostring(bullVol, format.volume) + '\nSell: ' + str.tostring(bearVol, format.volume) + '\nDelta Vol: ' + delta_volume_abs + '\nDelta %: ' + delta_volume, color=color.new(vidya_trend_color, 90), style=is_vidya_up ? label.style_label_upper_left : label.style_label_lower_left, textcolor=chart.fg_color, size=size.small)
- if not na(vidya_trend_star_label)
- label.delete(vidya_trend_star_label)
- vidya_trend_star_label := label.new(bar_index, smoothed_value, text='✪', color=#00000003, textcolor=vidya_trend_color, style=label.style_label_center, size=size.large)
- else
- if not na(vidya_delta_volume_label)
- label.delete(vidya_delta_volume_label)
- vidya_delta_volume_label := na
- if not na(vidya_trend_star_label)
- label.delete(vidya_trend_star_label)
- vidya_trend_star_label := na
- s1 = request.security(syminfo.tickerid, t1, f_vidya_trend(sourceVIDYA)[1], lookahead=barmerge.lookahead_on)
- s2 = request.security(syminfo.tickerid, t2, f_vidya_trend(sourceVIDYA)[1], lookahead=barmerge.lookahead_on)
- s3 = request.security(syminfo.tickerid, t3, f_vidya_trend(sourceVIDYA)[1], lookahead=barmerge.lookahead_on)
- s4 = request.security(syminfo.tickerid, t4, f_vidya_trend(sourceVIDYA)[1], lookahead=barmerge.lookahead_on)
- s5 = request.security(syminfo.tickerid, t5, f_vidya_trend(sourceVIDYA)[1], lookahead=barmerge.lookahead_on)
- bool tf_buy_ok = (not active_t1 or s1 == 1) and (not active_t2 or s2 == 1) and (not active_t3 or s3 == 1) and (not active_t4 or s4 == 1) and (not active_t5 or s5 == 1)
- bool tf_sell_ok = (not active_t1 or s1 == -1) and (not active_t2 or s2 == -1) and (not active_t3 or s3 == -1) and (not active_t4 or s4 == -1) and (not active_t5 or s5 == -1)
- int activeTFCount = (active_t1 ? 1 : 0) + (active_t2 ? 1 : 0) + (active_t3 ? 1 : 0) + (active_t4 ? 1 : 0) + (active_t5 ? 1 : 0)
- bool allActiveBullish = activeTFCount > 0 and (not active_t1 or s1 == 1) and (not active_t2 or s2 == 1) and (not active_t3 or s3 == 1) and (not active_t4 or s4 == 1) and (not active_t5 or s5 == 1)
- bool allActiveBearish = activeTFCount > 0 and (not active_t1 or s1 == -1) and (not active_t2 or s2 == -1) and (not active_t3 or s3 == -1) and (not active_t4 or s4 == -1) and (not active_t5 or s5 == -1)
- string tfConsensus = activeTFCount == 0 ? "Disabled" : allActiveBullish ? "Bullish" : allActiveBearish ? "Bearish" : "Mixed"
- color tfConsensusColor = activeTFCount == 0 ? color.gray : allActiveBullish ? color.lime : allActiveBearish ? color.red : color.yellow
- tfStatus(bool active, int sign) =>
- active ? (sign == 1 ? "Bullish" : sign == -1 ? "Bearish" : "Neutral") : "Disabled"
- string tf1Status = tfStatus(active_t1, s1)
- string tf2Status = tfStatus(active_t2, s2)
- string tf3Status = tfStatus(active_t3, s3)
- string tf4Status = tfStatus(active_t4, s4)
- string tf5Status = tfStatus(active_t5, s5)
- tfStatusColor(bool active, int sign) =>
- active ? (sign == 1 ? color.lime : sign == -1 ? color.red : color.gray) : color.gray
- color tf1Color = tfStatusColor(active_t1, s1)
- color tf2Color = tfStatusColor(active_t2, s2)
- color tf3Color = tfStatusColor(active_t3, s3)
- color tf4Color = tfStatusColor(active_t4, s4)
- color tf5Color = tfStatusColor(active_t5, s5)
- // --- Persistent Variables ---
- var float up_prob = 0.0
- var float dn_prob = 0.0
- var int up_cons = 0
- var int dn_cons = 0
- var bool gapTriggeredToday = false
- // --- Time & Session Logic ---
- // Detect the final bars of the normal trading session
- int nyHour = hour(time, "America/New_York")
- int nyMin = minute(time, "America/New_York")
- // Identify the execution window (target the 15:55 bar to lock in structure strictly near market close)
- bool isEndOfDayWindow = (nyHour == 15 and nyMin >= 55)
- bool newDay = ta.change(time("D", "America/New_York")) != 0
- if newDay
- up_prob := 0.0
- dn_prob := 0.0
- up_cons := 0
- dn_cons := 0
- gapTriggeredToday := false
- // --- Price & Structural Data ---
- var float dHigh = high
- var float dLow = low
- if newDay
- dHigh := high
- dLow := low
- else
- dHigh := math.max(dHigh, high)
- dLow := math.min(dLow, low)
- float day_range = dHigh - dLow
- float pos_score = day_range != 0 ? (close - dLow) / day_range : 0.0
- // Safely pull session VWAP, fallback to EMA for volumeless instruments (SPX)
- float v_wap = ta.vwap
- if na(v_wap)
- v_wap := ta.ema(close, 30)
- // --- Contextual Proxies (Non-Repainting) ---
- // Using closed bars [1] for security to avoid repainting intraday on historical data
- float es_close = nz(request.security("CME_MINI:ES1!", timeframe.period, close[1], lookahead=barmerge.lookahead_on))
- float es_ema = nz(request.security("CME_MINI:ES1!", timeframe.period, ta.ema(close, 10)[1], lookahead=barmerge.lookahead_on))
- float vix_close = nz(request.security("CBOE:VIX", timeframe.period, close[1], lookahead=barmerge.lookahead_on))
- float vix_sma = nz(request.security("CBOE:VIX", timeframe.period, ta.sma(close, 10)[1], lookahead=barmerge.lookahead_on))
- // --- Continuous Probability Engine ---
- float final_up_prob = 0.0
- float final_dn_prob = 0.0
- // 1. Structural Conditions (Loosened slightly to account for high-range chop, exported to data window)
- bool bull_structure = close > v_wap and pos_score >= 0.65
- bool bear_structure = close < v_wap and pos_score <= 0.35
- // --- Momentum Evaluators ---
- // Method 1: 1-Bar Quick
- bool vix_up_1 = vix_close < nz(vix_close[1])
- bool vix_dn_1 = vix_close > nz(vix_close[1])
- bool es_up_1 = es_close > nz(es_close[1])
- bool es_dn_1 = es_close < nz(es_close[1])
- // Method 2: 3-Bar SMA
- bool vix_up_2 = ta.sma(vix_close, gapAnchorBars) < nz(ta.sma(vix_close, gapAnchorBars)[1])
- bool vix_dn_2 = ta.sma(vix_close, gapAnchorBars) > nz(ta.sma(vix_close, gapAnchorBars)[1])
- bool es_up_2 = ta.sma(es_close, gapAnchorBars) > nz(ta.sma(es_close, gapAnchorBars)[1])
- bool es_dn_2 = ta.sma(es_close, gapAnchorBars) < nz(ta.sma(es_close, gapAnchorBars)[1])
- // Method 3: Avg Momentum
- bool vix_up_3 = ta.sma(ta.change(vix_close), gapAnchorBars) < 0
- bool vix_dn_3 = ta.sma(ta.change(vix_close), gapAnchorBars) > 0
- bool es_up_3 = ta.sma(ta.change(es_close), gapAnchorBars) > 0
- bool es_dn_3 = ta.sma(ta.change(es_close), gapAnchorBars) < 0
- // Method 4: Anchored Delta
- bool vix_up_4 = vix_close < nz(vix_close[gapAnchorBars])
- bool vix_dn_4 = vix_close > nz(vix_close[gapAnchorBars])
- bool es_up_4 = es_close > nz(es_close[gapAnchorBars])
- bool es_dn_4 = es_close < nz(es_close[gapAnchorBars])
- // Momentum Consensus Score
- int vix_up_score = (vix_up_1 ? 1 : 0) + (vix_up_2 ? 1 : 0) + (vix_up_3 ? 1 : 0) + (vix_up_4 ? 1 : 0)
- int vix_dn_score = (vix_dn_1 ? 1 : 0) + (vix_dn_2 ? 1 : 0) + (vix_dn_3 ? 1 : 0) + (vix_dn_4 ? 1 : 0)
- int es_up_score = (es_up_1 ? 1 : 0) + (es_up_2 ? 1 : 0) + (es_up_3 ? 1 : 0) + (es_up_4 ? 1 : 0)
- int es_dn_score = (es_dn_1 ? 1 : 0) + (es_dn_2 ? 1 : 0) + (es_dn_3 ? 1 : 0) + (es_dn_4 ? 1 : 0)
- bool vix_mom_up = vix_up_score >= gapConsensusReq
- bool vix_mom_dn = vix_dn_score >= gapConsensusReq
- bool es_mom_up = es_up_score >= gapConsensusReq
- bool es_mom_dn = es_dn_score >= gapConsensusReq
- // 2. VIX Momentum
- bool vix_confirms_up = vix_close < vix_sma and vix_mom_up
- bool vix_confirms_dn = vix_close > vix_sma and vix_mom_dn
- // 3. Futures Pressure
- bool es_bullish_trend = es_close > es_ema and es_mom_up
- bool es_bearish_trend = es_close < es_ema and es_mom_dn
- // --- GAP UP LOGIC ---
- if bull_structure and vix_confirms_up and es_bullish_trend
- final_up_prob := 95.0
- else if bull_structure and (vix_confirms_up or es_bullish_trend)
- final_up_prob := 80.0
- else if bull_structure
- final_up_prob := 60.0
- // --- GAP DOWN LOGIC (Stricter Requirements) ---
- if bear_structure and vix_confirms_dn and es_bearish_trend
- final_dn_prob := 95.0
- else if bear_structure and (vix_confirms_dn or es_bearish_trend)
- final_dn_prob := 80.0
- else if bear_structure
- final_dn_prob := 60.0
- // Invalidate Gap Down if VIX is dropping (Institutional Buying)
- if vix_mom_up
- final_dn_prob := 0.0
- if not gapTriggeredToday
- up_prob := final_up_prob
- dn_prob := final_dn_prob
- // Display the highest driving consensus for active structures, or 0 if probability is blocked
- up_cons := final_up_prob > 0 ? math.max(vix_up_score, es_up_score) : 0
- dn_cons := final_dn_prob > 0 ? math.max(vix_dn_score, es_dn_score) : 0
- // --- Execution Logic ---
- // We target the first bar in the end of day window.
- bool gapBuyCandidate = useOvernightGap and isEndOfDayWindow and not gapTriggeredToday and up_prob >= gapProbThreshold
- bool gapSellCandidate = useOvernightGap and isEndOfDayWindow and not gapTriggeredToday and dn_prob >= gapProbThreshold
- bool overnightGapBuy = gapBuyCandidate
- bool overnightGapSell = gapSellCandidate
- // Only lock out subsequent candles after a signal fully closes, preventing multiple triggers in the window
- if (gapBuyCandidate or gapSellCandidate)
- if barstate.isconfirmed
- gapTriggeredToday := true
- // --- Plotting ---
- // Plotting as columns for the final minute of the day
- plot(up_prob, "Gap Up Prob", color=color.new(color.blue, 0), style=plot.style_line, linewidth=4, display=display.data_window)
- plot(dn_prob * -1, "Gap Down Prob", color=color.new(color.orange, 0), style=plot.style_line, linewidth=4, display=display.data_window)
- plot(pos_score * 100, "Position Score %", color=color.new(color.white, 80), display=display.data_window)
- plot(v_wap, "Gap VWAP", color=color.new(color.fuchsia, 50), display=display.data_window)
- float v_roc = ta.change(vidya_value)
- float abs_v_roc_z = math.abs(v_roc / ta.stdev(v_roc, 200))
- bool isFlat = nz(abs_v_roc_z) < vidya_flat_cutoff
- bool isWeak = nz(abs_v_roc_z) >= vidya_flat_cutoff and nz(abs_v_roc_z) < vidya_weak_cutoff
- bool isModerate = nz(abs_v_roc_z) >= vidya_weak_cutoff and nz(abs_v_roc_z) < vidya_moderate_cutoff
- bool isStrong = nz(abs_v_roc_z) >= vidya_moderate_cutoff
- color vidyaSlopeColor = isStrong ? color.green : isModerate ? color.yellow : isWeak ? color.red : color.gray
- plot(showVIDYA_SlopeHistogram ? abs_v_roc_z : na, title="VIDYA Slope Z-Score", color=vidyaSlopeColor, style=plot.style_columns, linewidth=3, display=showVIDYA_SlopeHistogram ? display.pane : display.none)
- hline(vidya_flat_cutoff, title="Flat/Weak Threshold", color=color.new(color.gray, 50), linestyle=hline.style_dotted)
- hline(vidya_weak_cutoff, title="Weak/Moderate Threshold", color=color.new(color.gray, 50), linestyle=hline.style_dotted)
- hline(vidya_moderate_cutoff, title="Moderate/Strong Threshold", color=color.new(color.gray, 50), linestyle=hline.style_dotted)
- bool slope_aligned_ok = (allowAlignedFlat and isFlat) or (allowAlignedWeak and isWeak) or (allowAlignedModerate and isModerate) or (allowAlignedStrong and isStrong)
- bool slope_contra_ok = (allowContraFlat and isFlat) or (allowContraWeak and isWeak) or (allowContraModerate and isModerate) or (allowContraStrong and isStrong)
- bool vidya_buy_ok = (is_vidya_up and slope_aligned_ok) or (not is_vidya_up and slope_contra_ok)
- bool vidya_sell_ok = (not is_vidya_up and slope_aligned_ok) or (is_vidya_up and slope_contra_ok)
- if showTfTable and barstate.islast
- table.cell(statusTable, 0, 0, "TimeFrame Consensus", text_color=color.white, bgcolor=color.new(color.gray, 80))
- table.cell(statusTable, 1, 0, tfConsensus, text_color=tfConsensusColor, bgcolor=color.new(color.gray, 80))
- table.cell(statusTable, 0, 1, t1, text_color=color.white)
- table.cell(statusTable, 1, 1, tf1Status, text_color=tf1Color)
- table.cell(statusTable, 0, 2, t2, text_color=color.white)
- table.cell(statusTable, 1, 2, tf2Status, text_color=tf2Color)
- table.cell(statusTable, 0, 3, t3, text_color=color.white)
- table.cell(statusTable, 1, 3, tf3Status, text_color=tf3Color)
- table.cell(statusTable, 0, 4, t4, text_color=color.white)
- table.cell(statusTable, 1, 4, tf4Status, text_color=tf4Color)
- table.cell(statusTable, 0, 5, t5, text_color=color.white)
- table.cell(statusTable, 1, 5, tf5Status, text_color=tf5Color)
- else if not showTfTable
- table.clear(statusTable, 0, 0, 1, 5)
- // --- Trend Conditioning Logic ---
- // Top Finder (Sells only)
- bool top_tf_ok = topFilterLogic == "Contrarian" ? tf_buy_ok : tf_sell_ok
- bool top_vidya_ok = topFilterLogic == "Contrarian" ? vidya_buy_ok : vidya_sell_ok
- bool topStrongFiltered = useTop and strongTopConfirmed and (not topFilterByTF or top_tf_ok) and (not topFilterByVIDYA or top_vidya_ok)
- bool topModerateFiltered = useTop and moderateTopConfirmed and (not topFilterByTF or top_tf_ok) and (not topFilterByVIDYA or top_vidya_ok)
- // Bottom Finder (Buys only)
- bool bot_tf_ok = botFilterLogic == "Contrarian" ? tf_sell_ok : tf_buy_ok
- bool bot_vidya_ok = botFilterLogic == "Contrarian" ? vidya_sell_ok : vidya_buy_ok
- bool bottomWeakFiltered = useBot and bottomWeakSignal and (not botFilterByTF or bot_tf_ok) and (not botFilterByVIDYA or bot_vidya_ok)
- bool bottomModerateFiltered = useBot and bottomModerateSignal and (not botFilterByTF or bot_tf_ok) and (not botFilterByVIDYA or bot_vidya_ok)
- bool bottomStrongFiltered = useBot and bottomStrongSignal and (not botFilterByTF or bot_tf_ok) and (not botFilterByVIDYA or bot_vidya_ok)
- bool momentumBuyFiltered = useBot and momentumBuySignal and (not botFilterByTF or bot_tf_ok) and (not botFilterByVIDYA or bot_vidya_ok)
- // HF Signals (Buys and Sells)
- bool hf_buy_tf_ok = hfFilterLogic == "Contrarian" ? tf_sell_ok : tf_buy_ok
- bool hf_buy_vidya_ok = hfFilterLogic == "Contrarian" ? vidya_sell_ok : vidya_buy_ok
- bool hf_sell_tf_ok = hfFilterLogic == "Contrarian" ? tf_buy_ok : tf_sell_ok
- bool hf_sell_vidya_ok = hfFilterLogic == "Contrarian" ? vidya_buy_ok : vidya_sell_ok
- bool hfBuyFiltered = useHfSignals and buySignalB and (not hfFilterByTF or hf_buy_tf_ok) and (not hfFilterByVIDYA or hf_buy_vidya_ok)
- bool hfSellFiltered = useHfSignals and sellSignalB and (not hfFilterByTF or hf_sell_tf_ok) and (not hfFilterByVIDYA or hf_sell_vidya_ok)
- // Overnight Gap (Buys and Sells)
- bool gap_buy_tf_ok = gapFilterLogic == "Contrarian" ? tf_sell_ok : tf_buy_ok
- bool gap_buy_vidya_ok = gapFilterLogic == "Contrarian" ? vidya_sell_ok : vidya_buy_ok
- bool gap_sell_tf_ok = gapFilterLogic == "Contrarian" ? tf_buy_ok : tf_sell_ok
- bool gap_sell_vidya_ok = gapFilterLogic == "Contrarian" ? vidya_buy_ok : vidya_sell_ok
- bool overnightGapBuyFiltered = overnightGapBuy and (not gapFilterByTF or gap_buy_tf_ok) and (not gapFilterByVIDYA or gap_buy_vidya_ok)
- bool overnightGapSellFiltered = overnightGapSell and (not gapFilterByTF or gap_sell_tf_ok) and (not gapFilterByVIDYA or gap_sell_vidya_ok)
- // --- Plotting ---
- plotshape(useTop and showTopStrong and topStrongFiltered, title="Top Strong Sell", style=shape.labeldown, location=location.abovebar, color=topStrongLabelColor, text="Sell", textcolor=topStrongTextColor, size=size.tiny)
- plotshape(useTop and showTopModerate and topModerateFiltered, title="Top Moderate Sell", style=shape.labeldown, location=location.abovebar, color=topModerateLabelColor, text="Sell", textcolor=topModerateTextColor, size=size.tiny)
- plotshape((showBottomWeak and bottomWeakFiltered) or (showBottomModerate and bottomModerateFiltered) or (showBottomStrong and bottomStrongFiltered), title="Bottom Buy", style=shape.labelup, location=location.belowbar, color=color.new(bottomLongColor, 0), text="Buy", textcolor=bottomTextColor, size=size.tiny)
- plotshape(momentumBuyFiltered, title="Bottom Momentum Buy", style=shape.labelup, location=location.belowbar, color=momentumLabelColor, text="Buy", textcolor=momentumTextColor, size=size.small)
- plotshape(hfBuyFiltered, title="hf_signals Buy", style=shape.labelup, location=location.belowbar, color=hfSignalsBuyLabelColor, text="HF Buy", textcolor=hfSignalsBuyTextColor, size=size.tiny)
- plotshape(hfSellFiltered, title="hf_signals Sell", style=shape.labeldown, location=location.abovebar, color=hfSignalsSellLabelColor, text="HF Sell", textcolor=hfSignalsSellTextColor, size=size.tiny)
- if overnightGapBuyFiltered and showOvernightGapBuy
- label.new(bar_index, low, "GAP UP\n" + str.tostring(up_prob) + "% (C:" + str.tostring(up_cons) + "/4)", style=label.style_label_up, color=color.new(color.blue, 0), textcolor=color.white, size=size.normal)
- if overnightGapSellFiltered and showOvernightGapSell
- label.new(bar_index, high, "GAP DN\n" + str.tostring(dn_prob) + "% (C:" + str.tostring(dn_cons) + "/4)", style=label.style_label_down, color=color.new(color.orange, 0), textcolor=color.white, size=size.normal)
- weakAlert = bottomWeakFiltered and weakAlertsEnabled
- moderateAlert = bottomModerateFiltered and moderateAlertsEnabled
- strongAlert = bottomStrongFiltered and strongAlertsEnabled
- momentumAlert = momentumBuyFiltered and momentumAlertsEnabled
- alertcondition(topStrongFiltered and topStrongAlertsEnabled, title="Strong Sell Signal", message="Strong sell signal detected")
- alertcondition(topModerateFiltered and topModerateAlertsEnabled, title="Moderate Sell Signal", message="Moderate sell signal detected")
- alertcondition(weakAlert, title="Weak Buy Signal", message="Weak buy signal detected")
- alertcondition(moderateAlert, title="Moderate Buy Signal", message="Moderate buy signal detected")
- alertcondition(strongAlert, title="Strong Buy Signal", message="Strong buy signal detected")
- alertcondition(momentumAlert, title="Momentum Buy Signal", message="Momentum buy signal detected")
- alertcondition(hfBuyFiltered and hfBuyAlertsEnabled, title="HF Buy Signal", message="Buy: hf_signals")
- alertcondition(hfSellFiltered and hfSellAlertsEnabled, title="HF Sell Signal", message="Sell: hf_signals")
- alertcondition(overnightGapBuyFiltered and overnightGapAlertsEnabled, title="Overnight Gap Buy", message="Overnight Gap buy signal")
- alertcondition(overnightGapSellFiltered and overnightGapAlertsEnabled, title="Overnight Gap Sell", message="Overnight Gap sell signal")
- // === Webhook / Dynamic Alert Logic ===
- // This function constructs a JSON string to send to your webhook. This permits a precise signal description with just one webhook
- // Ex: {"ticker": "BTCUSDT", "price": "65432.10", "value_text": "Strong Sell", value_float:-1.0, direction:"bearish", action:"sell"}
- // How to set up the WebhookOnce you have saved the modified code and added the script to your chart:
- // -- Click the Alerts icon (clock) on the right sidebar or press Alt + A.
- // -- Condition: Select BotBoys SuperScript [FTF].
- // -- Action: Select "Any alert() function call". This is crucial; it tells TradingView to listen to the code we just added rather than the old static alert conditions.
- // -- Notification Tab:
- // -- Check Webhook URL.
- // -- Paste your destination URL (e.g., from Discord, Zapier, or your trading bot).
- // -- Message Box: You can leave this as {{strategy.order.alert_message}} or simply {{alert_message}}. Because we defined the message inside the alert() function in the code, TradingView will pass that JSON string directly to your webhook.
- // Helper function to generate the JSON payload
- get_payload(name, valFloat, dir, act) =>
- string expiry = str.tostring(timenow + (alertExpiry * 60000))
- '{"ticker": "' + syminfo.ticker +
- '", "price": "' + str.tostring(close) +
- '", "value_text": "'+ name +
- '", "value_float": '+ str.tostring(valFloat) +
- ', "direction": "' + dir +
- '", "action": "' + act +
- '", "secret_key": "' + webhookKey +
- '", "expires_at": ' + expiry + '}'
- // Top Finder Signals
- if topStrongFiltered
- alert(get_payload("Strong Sell", -1.0, "bearish", "sell"), alert.freq_once_per_bar)
- if topModerateFiltered
- alert(get_payload("Moderate Sell", -1.0, "bearish", "sell"), alert.freq_once_per_bar)
- // Bottom Finder Signals
- if weakAlert
- alert(get_payload("Weak Buy", 1.0, "bullish", "buy"), alert.freq_once_per_bar)
- if moderateAlert
- alert(get_payload("Moderate Buy", 1.0, "bullish", "buy"), alert.freq_once_per_bar)
- if strongAlert
- alert(get_payload("Strong Buy", 1.0, "bullish", "buy"), alert.freq_once_per_bar)
- if momentumAlert
- alert(get_payload("Momentum Buy", 1.0, "bullish", "buy"), alert.freq_once_per_bar)
- // HF Signals
- if hfBuyFiltered and hfBuyAlertsEnabled
- alert(get_payload("HF Buy", 1.0, "bullish", "buy"), alert.freq_once_per_bar)
- if hfSellFiltered and hfSellAlertsEnabled
- alert(get_payload("HF Sell", -1.0, "bearish", "sell"), alert.freq_once_per_bar)
- // Overnight Gap Signals
- if overnightGapBuyFiltered and overnightGapAlertsEnabled
- alert(get_payload("Overnight Gap Buy (Prob: " + str.tostring(up_prob) + "% | C:" + str.tostring(up_cons) + "/4)", 1.0, "bullish", "buy"), alert.freq_once_per_bar)
- if overnightGapSellFiltered and overnightGapAlertsEnabled
- alert(get_payload("Overnight Gap Sell (Prob: " + str.tostring(dn_prob) + "% | C:" + str.tostring(dn_cons) + "/4)", -1.0, "bearish", "sell"), alert.freq_once_per_bar)
- // --- SPY / ES / SPX Converter ---
- float spyClose = showConverter ? request.security("AMEX:SPY", timeframe.period, close) : na
- float esClose = showConverter ? request.security("CME_MINI:ES1!", timeframe.period, close) : na
- float spxClose = showConverter ? request.security("SP:SPX", timeframe.period, close) : na
- var table tblConv = na
- if showConverter and barstate.islast
- string tablePosStr = convPositionStr == "Bottom Right" ? position.bottom_right : convPositionStr == "Top Right" ? position.top_right : convPositionStr == "Bottom Left" ? position.bottom_left : position.top_left
- tblConv := table.new(tablePosStr, 4, 4, border_width=1, frame_color=color.new(color.gray, 80), border_color=color.new(color.gray, 80), bgcolor=color.new(color.black, 90))
- table.cell(tblConv, 0, 0, "Symbol", text_color=color.white, bgcolor=color.new(color.gray, 80))
- table.cell(tblConv, 1, 0, "Price", text_color=color.white, bgcolor=color.new(color.gray, 80))
- table.cell(tblConv, 2, 0, "to SPX", text_color=color.white, bgcolor=color.new(color.gray, 80))
- table.cell(tblConv, 3, 0, "Result", text_color=color.white, bgcolor=color.new(color.gray, 80))
- table.cell(tblConv, 0, 1, "SPY", text_color=color.white)
- table.cell(tblConv, 1, 1, str.tostring(spyClose, format.mintick), text_color=color.white)
- table.cell(tblConv, 2, 1, "x" + str.tostring(spxClose / spyClose, "#.####"), text_color=color.white)
- table.cell(tblConv, 3, 1, str.tostring(spyClose * (spxClose / spyClose), format.mintick), text_color=color.white)
- table.cell(tblConv, 0, 2, "ES", text_color=color.white)
- table.cell(tblConv, 1, 2, str.tostring(esClose, format.mintick), text_color=color.white)
- float esOffset = spxClose - esClose
- string esOffStr = (esOffset >= 0 ? "+" : "") + str.tostring(esOffset, "#.##")
- table.cell(tblConv, 2, 2, esOffStr, text_color=color.white)
- table.cell(tblConv, 3, 2, str.tostring(esClose + esOffset, format.mintick), text_color=color.white)
- table.cell(tblConv, 0, 3, "SPX", text_color=color.white)
- table.cell(tblConv, 1, 3, str.tostring(spxClose, format.mintick), text_color=color.white)
- table.cell(tblConv, 2, 3, "-", text_color=color.white)
- table.cell(tblConv, 3, 3, str.tostring(spxClose, format.mintick), text_color=color.white)
Advertisement
Add Comment
Please, Sign In to add comment