Indicator · Pine Script v6 · Own pane

Kernal Cipher 2

by kdricha0602

Kernal Cipher 2 is a lower-pane signal panel.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code532
Settings40inputs
LicenceMIT
Last update5 weeks ago21 Sep 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

532 lines of Pine Script v6 from archive/Kernal-Cipher-2.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.

Kernal-Cipher-2.pine
//@version=6
// ═══════════════════════════════════════════════════════════════════════════
//  KERNAL CIPHER 2 — Signal Panel (renamed 2026-09-20;
//  formerly "Kernal Quantizer KOK 2" / "Quantkiller KOK 2")
//  Lower pane for "Kernal Cipher 1".
//  Green diamonds = BUY · Red diamonds = SELL (large = STRONG) ·
//  diamond tags: BO = breakout, CONT = continuation, REV = reversal ·
//  hollow gray diamonds = signal blocked by the anti-chase filter ·
//  confluence score histogram (max |12|) ·
//  VOLUME STRIP pinned to the LEFT edge: gold = volume at or above the
//  Volume Surge Level (default 1.5x of the volume baseline),
//  dashed gold line = the surge threshold.
//  2026-09-20 FEAR/GREED + VIX: the KC3-validated 7-component Fear/Greed gauge
//  and both decision gates (FG block, VIX calm) are wired into the panel's
//  signal logic with identical math and defaults, so the panel's diamonds
//  and alerts agree with what KC3 trades. Gauge plotted in its own pane.
//  Alerts live here — one shot per signal.
// ═══════════════════════════════════════════════════════════════════════════

indicator("Kernal Cipher 2", shorttitle="KC2", overlay=false, max_boxes_count=500, max_lines_count=500)

GRP_T   = "01 · Trend"
GRP_ST  = "02 · Supertrend"
GRP_RG  = "03 · Regime"
GRP_WT  = "04 · WaveTrend"
GRP_SR  = "05 · StochRSI"
GRP_DV  = "06 · Divergence"
GRP_RS  = "07 · Relative Strength & Beta"
GRP_ATR = "08 · ATR / Volatility / Risk"
GRP_VL  = "09 · Volume"
GRP_SG  = "10 · Signals"
GRP_FG  = "11 · Fear & Greed"
GRP_DS  = "12 · Display"
GRP_WC  = "13 · White Candle Event"

emaFastLen = input.int(21, "EMA Fast", minval=2, group=GRP_T)
emaSlowLen = input.int(50, "EMA Slow", minval=3, group=GRP_T)
emaLongLen = input.int(200, "EMA Long / Regime", minval=20, group=GRP_T)
slopeLen = input.int(5, "EMA Slope Lookback", minval=1, group=GRP_T)
minSlopePct = input.float(0.05, "Minimum EMA Slope %", step=0.01, group=GRP_T)
stLen  = input.int(10, "ATR Length", minval=1, group=GRP_ST)
stMult = input.float(3.0, "Multiplier", minval=0.1, step=0.1, group=GRP_ST)
adxLen = input.int(14, "ADX Length", minval=2, group=GRP_RG)
adxThresh = input.int(20, "ADX Minimum", minval=5, group=GRP_RG)
requireDiAlignment = input.bool(true, "Require DI Alignment", group=GRP_RG)
wtN1 = input.int(10, "Channel Length", minval=1, group=GRP_WT)
wtN2 = input.int(21, "Average Length", minval=1, group=GRP_WT)
rsiLen = input.int(14, "RSI Length", minval=2, group=GRP_SR)
stochLen = input.int(14, "Stochastic Length", minval=2, group=GRP_SR)
smoothK = input.int(3, "Smooth K", minval=1, group=GRP_SR)
smoothD = input.int(3, "Smooth D", minval=1, group=GRP_SR)
stochLongMax = input.float(80, "Maximum K for Long Entry", minval=1, maxval=100, group=GRP_SR)
stochShortMin = input.float(20, "Minimum K for Short Entry", minval=0, maxval=99, group=GRP_SR)
lbL = input.int(5, "Pivot Lookback Left", minval=1, group=GRP_DV)
lbR = input.int(5, "Pivot Lookback Right", minval=1, group=GRP_DV)
divMinBars = input.int(5, "Min Bars Between Pivots", minval=1, group=GRP_DV)
divMaxBars = input.int(60, "Max Bars Between Pivots", minval=2, group=GRP_DV)
useRSFilter = input.bool(true, "Use Relative Strength Filter", group=GRP_RS)
bench1 = input.symbol("AMEX:SPY", "Primary Benchmark", group=GRP_RS)
bench2 = input.symbol("NASDAQ:QQQ", "Secondary Benchmark", group=GRP_RS)
rsLen = input.int(20, "RS Lookback", minval=2, group=GRP_RS)
rsLongMin = input.float(0.0, "Minimum RS % for Longs", step=0.1, group=GRP_RS)
rsShortMax = input.float(0.0, "Maximum RS % for Shorts", step=0.1, group=GRP_RS)
betaLen = input.int(60, "Beta Lookback", minval=10, group=GRP_RS)
betaMin = input.float(0.7, "Minimum Beta for Longs", minval=0, step=0.1, group=GRP_RS)
useBetaFilter = input.bool(false, "Require Minimum Beta for Longs", group=GRP_RS)
atrLen = input.int(14, "ATR Length", minval=1, group=GRP_ATR)
atrStopMult = input.float(2.0, "ATR Stop Multiplier", minval=0.5, step=0.1, group=GRP_ATR)
atrRegimeLen = input.int(50, "ATR Regime Baseline", minval=5, group=GRP_ATR)
atrExpansionMin = input.float(0.80, "Min ATR / ATR Baseline", minval=0.1, step=0.05, group=GRP_ATR)
atrExpansionMax = input.float(3.00, "Max ATR / ATR Baseline", minval=0.5, step=0.1, group=GRP_ATR)
maxChaseATR = input.float(1.5, "Max Distance From Fast EMA (ATR)", minval=0.25, step=0.25, group=GRP_ATR)
volLen = input.int(20, "Volume Baseline Length", minval=2, group=GRP_VL)
rvolMin = input.float(1.20, "Minimum RVOL", minval=0.1, step=0.05, group=GRP_VL)
rvolStrong = input.float(2.00, "Strong RVOL", minval=0.5, step=0.1, group=GRP_VL)
volumeSurgeLevel = input.float(1.50, "Volume Surge Level (strip)", minval=0.5, step=0.05, group=GRP_VL)
useVolFilter = input.bool(true, "Require Volume Confirmation", group=GRP_VL)
showVolStrip = input.bool(true, "Show Volume Strip (left side)", group=GRP_VL)
volStripBars = input.int(40, "Volume Strip Bars", minval=10, maxval=100, group=GRP_VL)

// ── 13 White Candle Event ──
useWhiteCandle = input.bool(true, "Flag White-Candle Event", group=GRP_WC, tooltip="Flags the bar when total volume is slightly below average but buying dominates the tape and price range stretches beyond ATR.")
wcVolLow = input.float(0.70, "Volume Lower Bound (× avg)", minval=0.1, step=0.05, group=GRP_WC)
wcVolHigh = input.float(1.00, "Volume Upper Bound (× avg)", minval=0.5, step=0.05, group=GRP_WC)
wcBuyFrac = input.float(0.65, "Min Buy-Share Fraction", minval=0.5, maxval=1.0, step=0.05, group=GRP_WC, tooltip="Estimated share of volume on the buy side: (close-low)/(high-low).")
wcAtrMult = input.float(1.00, "Range Expansion (× ATR)", minval=0.25, step=0.25, group=GRP_WC)
wcMirror = input.bool(true, "Flag Sell-Side Mirror", group=GRP_WC)
regimeWeight = input.int(2, "Regime Weight", minval=1, maxval=4, group=GRP_SG)
emaWeight = input.int(2, "EMA Weight", minval=1, maxval=4, group=GRP_SG)
stWeight = input.int(2, "Supertrend Weight", minval=1, maxval=4, group=GRP_SG)
slopeWeight = input.int(1, "Slope Weight", minval=0, maxval=3, group=GRP_SG)
wtWeight = input.int(1, "WaveTrend Weight", minval=0, maxval=3, group=GRP_SG)
srWeight = input.int(1, "StochRSI Weight", minval=0, maxval=3, group=GRP_SG)
divWeight = input.int(1, "Divergence Weight", minval=0, maxval=3, group=GRP_SG)
rsWeight = input.int(1, "Relative Strength Weight", minval=0, maxval=3, group=GRP_SG)
atrWeight = input.int(1, "ATR Weight", minval=0, maxval=3, group=GRP_SG)
longThresh = input.int(10, "Long Score Threshold", minval=1, maxval=20, group=GRP_SG)
shortThresh = input.int(10, "Short Score Threshold", minval=1, maxval=20, group=GRP_SG)
strongOffset = input.int(2, "Strong Signal Offset (score above threshold)", minval=1, maxval=5, group=GRP_SG)
cooldownBars = input.int(5, "Signal Cooldown Bars", minval=0, group=GRP_SG)
longOnly = input.bool(false, "Long Signals Only", group=GRP_SG)
breakoutLookback = input.int(20, "Breakout Lookback", minval=5, group=GRP_SG)

// ── Fear/Greed gauge (identical math + defaults to KC3) ──
useFG = input.bool(true, "Show Fear/Greed Gauge", group=GRP_FG)
showContract = input.bool(true, "Show Contract Strip (bottom-left fine print)", group=GRP_DS, tooltip="The decision contract: last signal, score vs trigger, and live gate state. Four rows, tiny text, bottom-left.")
fgSymVIX = input.symbol("TVC:VIX", "VIX Symbol (volatility)", group=GRP_FG)
fgSymHYG = input.symbol("AMEX:HYG", "High-Yield Bond Symbol", group=GRP_FG)
fgSymIEF = input.symbol("AMEX:IEF", "Treasury Bond Symbol", group=GRP_FG)
fgZLen = input.int(252, "Normalization Window (bars)", minval=50, group=GRP_FG)
fgMomLen = input.int(125, "Momentum SMA Length", minval=20, group=GRP_FG)
fgVixLen = input.int(50, "VIX SMA Length", minval=10, group=GRP_FG)
fgRetLen = input.int(20, "Return / Breadth Window", minval=5, group=GRP_FG)
fgRangeLen = input.int(252, "Strength Range Length", minval=50, group=GRP_FG)
fgFear = input.int(24, "Extreme Fear Zone (≤)", minval=1, maxval=49, group=GRP_FG)
fgGreed = input.int(76, "Extreme Greed Zone (≥)", minval=51, maxval=99, group=GRP_FG)
fgW1 = input.float(1.0, "Weight: Market Momentum", minval=0, step=0.5, group=GRP_FG)
fgW2 = input.float(1.0, "Weight: Price Strength", minval=0, step=0.5, group=GRP_FG)
fgW3 = input.float(1.0, "Weight: Breadth", minval=0, step=0.5, group=GRP_FG)
fgW4 = input.float(1.0, "Weight: Put/Call Proxy", minval=0, step=0.5, group=GRP_FG)
fgW5 = input.float(1.0, "Weight: Junk Bonds", minval=0, step=0.5, group=GRP_FG)
fgW6 = input.float(1.0, "Weight: Volatility", minval=0, step=0.5, group=GRP_FG)
fgW7 = input.float(1.0, "Weight: Safe Haven", minval=0, step=0.5, group=GRP_FG)
useFGBlock = input.bool(true, "Block Entries Against Extreme Crowd", group=GRP_FG)
useFGConv = input.bool(false, "Fear/Greed Conviction Boost", group=GRP_FG)
useVIXCalm = input.bool(true, "Longs Only When VIX Calm (VIX < SMA)", group=GRP_FG)
vixCalmLen = input.int(50, "VIX Calm SMA Length", minval=10, group=GRP_FG)
useVIXPanic = input.bool(false, "Skip Entries on VIX Panic Spike", group=GRP_FG)
vixPanicPct = input.float(15.0, "VIX Panic Spike % (day-over-day)", minval=5, step=1, group=GRP_FG)

// ── Engine (identical to overlay so signals always agree) ──
emaFast = ta.ema(close, emaFastLen)
emaSlow = ta.ema(close, emaSlowLen)
emaLong = ta.ema(close, emaLongLen)
emaBull = emaFast > emaSlow
emaBear = emaFast < emaSlow
emaSlopePct = not na(emaFast[slopeLen]) and emaFast[slopeLen] != 0 ? ((emaFast - emaFast[slopeLen]) / emaFast[slopeLen]) * 100 : 0
slopeBull = emaSlopePct >= minSlopePct
slopeBear = emaSlopePct <= -minSlopePct
[stLine, stDir] = ta.supertrend(stMult, stLen)
stBull = not na(stDir) and stDir < 0
stBear = not na(stDir) and stDir > 0
[dmp, dmn, adxV] = ta.dmi(adxLen, adxLen)
bullReg = not na(emaLong) and not na(adxV) and not na(dmp) and not na(dmn) and close > emaLong and adxV >= adxThresh and (not requireDiAlignment or dmp > dmn)
bearReg = not na(emaLong) and not na(adxV) and not na(dmp) and not na(dmn) and close < emaLong and adxV >= adxThresh and (not requireDiAlignment or dmn > dmp)
rangeReg = not bullReg and not bearReg
ap = hlc3
esa = ta.ema(ap, wtN1)
dd = ta.ema(math.abs(ap - esa), wtN1)
ci = dd == 0 ? 0 : (ap - esa) / (0.015 * dd)
wt1 = ta.ema(ci, wtN2)
wt2 = ta.sma(wt1, 4)
wtBull = wt1 > wt2
wtBear = wt1 < wt2
rsiV = ta.rsi(close, rsiLen)
k = ta.sma(ta.stoch(rsiV, rsiV, rsiV, stochLen), smoothK)
dSm = ta.sma(k, smoothD)
srBull = k > dSm
srBear = k < dSm
wtBullCross = ta.crossover(wt1, wt2)
wtBearCross = ta.crossunder(wt1, wt2)
srBullCross = ta.crossover(k, dSm)
srBearCross = ta.crossunder(k, dSm)
plFound = not na(ta.pivotlow(wt1, lbL, lbR))
phFound = not na(ta.pivothigh(wt1, lbL, lbR))
_inRange(cond) =>
    b = ta.barssince(cond)
    not na(b) and b >= divMinBars and b <= divMaxBars
inRangePl = _inRange(plFound[1])
inRangePh = _inRange(phFound[1])
prevPlO = ta.valuewhen(plFound, wt1[lbR], 1)
prevPlP = ta.valuewhen(plFound, low[lbR], 1)
prevPhO = ta.valuewhen(phFound, wt1[lbR], 1)
prevPhP = ta.valuewhen(phFound, high[lbR], 1)
curPlO = wt1[lbR]
curPlP = low[lbR]
curPhO = wt1[lbR]
curPhP = high[lbR]
validL = plFound and inRangePl and not na(prevPlO) and not na(prevPlP) and not na(curPlO) and not na(curPlP)
validH = phFound and inRangePh and not na(prevPhO) and not na(prevPhP) and not na(curPhO) and not na(curPhP)
bullDiv = validL and curPlO > prevPlO and curPlP < prevPlP
bearDiv = validH and curPhO < prevPhO and curPhP > prevPhP
hidBullDiv = validL and curPlO < prevPlO and curPlP > prevPlP
hidBearDiv = validH and curPhO > prevPhO and curPhP < prevPhP
atrV = ta.atr(atrLen)
atrBaseline = ta.sma(atrV, atrRegimeLen)
atrRatio = not na(atrBaseline) and atrBaseline != 0 ? atrV / atrBaseline : 1.0
volatilityOK = atrRatio >= atrExpansionMin and atrRatio <= atrExpansionMax
atrBull = volatilityOK and close > emaFast
atrBear = volatilityOK and close < emaFast
distanceATR = atrV != 0 ? math.abs(close - emaFast) / atrV : 0
notChasing = distanceATR <= maxChaseATR
benchSPY = request.security(bench1, timeframe.period, close)
benchQQQ = request.security(bench2, timeframe.period, close)
assetReturn = close[rsLen] != 0 ? ((close / close[rsLen]) - 1) * 100 : na
spyReturn = benchSPY[rsLen] != 0 ? ((benchSPY / benchSPY[rsLen]) - 1) * 100 : na
qqqReturn = benchQQQ[rsLen] != 0 ? ((benchQQQ / benchQQQ[rsLen]) - 1) * 100 : na
rsSPY = assetReturn - spyReturn
rsQQQ = assetReturn - qqqReturn
rsBull = not na(rsSPY) and not na(rsQQQ) and rsSPY >= rsLongMin and rsQQQ >= rsLongMin
rsBear = not na(rsSPY) and not na(rsQQQ) and rsSPY <= rsShortMax and rsQQQ <= rsShortMax
rsLongOK = not useRSFilter or rsBull
rsShortOK = not useRSFilter or rsBear
assetRet = math.log(close / close[1])
benchRet = math.log(benchSPY / benchSPY[1])
assetMean = ta.sma(assetRet, betaLen)
benchMean = ta.sma(benchRet, betaLen)
rollingCov = ta.sma(assetRet * benchRet, betaLen) - assetMean * benchMean
rollingVar = ta.sma(benchRet * benchRet, betaLen) - benchMean * benchMean
beta = rollingVar != 0 ? rollingCov / rollingVar : na
betaLongOK = not useBetaFilter or na(beta) or beta >= betaMin
volBaseline = ta.sma(nz(volume, 0), volLen)

// ── White-candle event: light total volume, heavy buy-share, range beyond ATR ──
wcRng = high - low
wcBuyShare = wcRng > 0 ? (close - low) / wcRng : 0.5
wcVolRatio = volBaseline > 0 ? nz(volume, 0) / volBaseline : na
wcVolLight = not na(wcVolRatio) and wcVolRatio >= wcVolLow and wcVolRatio < wcVolHigh
wcExpand = not na(atrV) and atrV > 0 and wcRng > wcAtrMult * atrV
whiteCandle = useWhiteCandle and wcVolLight and wcExpand and close > open and wcBuyShare >= wcBuyFrac
blackCandle = useWhiteCandle and wcMirror and wcVolLight and wcExpand and close < open and (1 - wcBuyShare) >= wcBuyFrac
var int wcBar = na
var int bcBar = na
if whiteCandle
    wcBar := bar_index
if blackCandle
    bcBar := bar_index
plotshape(useWhiteCandle and whiteCandle, title="White Candle", style=shape.diamond, location=location.bottom, color=color.white, size=size.tiny, text="W")
plotshape(useWhiteCandle and wcMirror and blackCandle, title="Black Candle", style=shape.diamond, location=location.top, color=color.black, size=size.tiny, text="B")
rvol = volBaseline > 0 ? nz(volume, 0) / volBaseline : 0
volOK = not useVolFilter or rvol >= rvolMin
volStrong = rvol >= rvolStrong

voteEMA = emaBull ? emaWeight : emaBear ? -emaWeight : 0
voteST = stBull ? stWeight : stBear ? -stWeight : 0
voteRegime = bullReg ? regimeWeight : bearReg ? -regimeWeight : 0
voteSlope = slopeBull ? slopeWeight : slopeBear ? -slopeWeight : 0
voteWT = wtBull ? wtWeight : wtBear ? -wtWeight : 0
voteSR = srBull ? srWeight : srBear ? -srWeight : 0
voteDiv = bullDiv or hidBullDiv ? divWeight : bearDiv or hidBearDiv ? -divWeight : 0
voteRS = rsBull ? rsWeight : rsBear ? -rsWeight : 0
voteATR = atrBull ? atrWeight : atrBear ? -atrWeight : 0
score = voteEMA + voteST + voteRegime + voteSlope + voteWT + voteSR + voteDiv + voteRS + voteATR
scoreSafe = nz(score, 0)

// ── QK Fear/Greed gauge: CNN 7-component methodology, chart data only ──
// Pine cannot fetch the CNN index over HTTP, so the gauge is rebuilt from
// market data. Construction mirrors CNN's published method (sources:
// investopedia.com/terms/f/fear-and-greed-index.asp and
// cnn.com/markets/fear-and-greed): 7 indicators, each scored 0-100, equally
// weighted (arithmetic mean), 50 = neutral. Normalization follows CNN's
// "how far they've veered from their average relative to how far they
// normally veer": z = (raw - trailing-window mean) / trailing-window stdev,
// score = 100 * Phi(z), inverted where high raw = fear. Zones: 0-24 Extreme
// Fear, 25-44 Fear, 45-55 Neutral, 56-75 Greed, 76-100 Extreme Greed.
// Calibrated for daily charts; market series are pulled on the daily
// timeframe regardless of chart timeframe.
mktD = request.security(bench1, "D", close)
fgZScore(raw) =>
    zm = ta.sma(raw, fgZLen)
    zs = ta.stdev(raw, fgZLen)
    not na(zm) and not na(zs) and zs != 0 ? (raw - zm) / zs : 0.0
// Abramowitz & Stegun 7.1.26 — erf to <1.5e-7 (Pine has no math.erf)
kcErf(x) =>
    a1  = 0.254829592
    a2  = -0.284496736
    a3  = 1.421413741
    a4  = -1.453152027
    a5  = 1.061405429
    p   = 0.3275911
    sgn = x < 0 ? -1.0 : 1.0
    ax  = math.abs(x)
    t   = 1.0 / (1.0 + p * ax)
    y   = 1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * math.exp(-ax * ax)
    sgn * y
fgPhi(z) =>
    0.5 * (1 + kcErf(z / 1.4142135623730951))

vixD = request.security(fgSymVIX, "D", close, barmerge.gaps_off, barmerge.lookahead_off)
hygD = request.security(fgSymHYG, "D", close, barmerge.gaps_off, barmerge.lookahead_off)
iefD = request.security(fgSymIEF, "D", close, barmerge.gaps_off, barmerge.lookahead_off)

// 1 · Market Momentum (CNN-exact): SPY vs its 125-day average
spySMA = ta.sma(mktD, fgMomLen)
fgR1 = not na(mktD) and not na(spySMA) and spySMA != 0 ? 100 * (mktD / spySMA - 1) : na
fgS1 = 100 * fgPhi(fgZScore(fgR1))
// 2 · Stock Price Strength (proxy for NYSE new highs minus new lows):
// where the close sits inside its 252-day high/low range, 0-100 as-is
hhR = ta.highest(high, fgRangeLen)
llR = ta.lowest(low, fgRangeLen)
fgR2 = not na(hhR) and not na(llR) and hhR != llR ? 100 * (close - llR) / (hhR - llR) : 50.0
fgS2 = math.max(0.0, math.min(100.0, fgR2))
// 3 · Stock Price Breadth (proxy for advancing/declining volume):
// share of 20-day volume printed on up days, z-scored
upV = close > close[1] ? nz(volume, 0) : 0.0
dnV = close < close[1] ? nz(volume, 0) : 0.0
upSum = math.sum(upV, fgRetLen)
dnSum = math.sum(dnV, fgRetLen)
fgR3 = upSum + dnSum > 0 ? upSum / (upSum + dnSum) : 0.5
fgS3 = 100 * fgPhi(fgZScore(fgR3))
// 4 · Put/Call proxy: distance from the 20-day high in ATRs.
// High hedging demand = fear, so the score is inverted.
hh20 = ta.highest(high, fgRetLen)
fgR4 = not na(hh20) and nz(atrV, 0) != 0 ? (hh20 - close) / nz(atrV, 0) : 0.0
fgS4 = 100 * (1 - fgPhi(fgZScore(fgR4)))
// 5 · Junk Bond Demand (real series): HYG 20-day return minus IEF 20-day return
rHYG = not na(hygD) and not na(hygD[fgRetLen]) and hygD[fgRetLen] != 0 ? hygD / hygD[fgRetLen] - 1 : na
rIEF = not na(iefD) and not na(iefD[fgRetLen]) and iefD[fgRetLen] != 0 ? iefD / iefD[fgRetLen] - 1 : na
fgR5 = not na(rHYG) and not na(rIEF) ? rHYG - rIEF : na
fgS5 = 100 * fgPhi(fgZScore(fgR5))
// 6 · Market Volatility (CNN-exact): VIX vs its 50-day average.
// High VIX = fear, so the score is inverted.
vixSMA = ta.sma(vixD, fgVixLen)
fgR6 = not na(vixD) and not na(vixSMA) and vixSMA != 0 ? vixD / vixSMA : na
fgS6 = 100 * (1 - fgPhi(fgZScore(fgR6)))
// VIX direct decision inputs (separate from the gauge component above)
vixCalmSMA = ta.sma(vixD, vixCalmLen)
vixCalm = not na(vixD) and not na(vixCalmSMA) and vixCalmSMA != 0 and vixD < vixCalmSMA
vixPanic = useVIXPanic and not na(vixD) and not na(vixD[1]) and vixD[1] != 0 and (vixD / vixD[1] - 1) * 100 > vixPanicPct
// 7 · Safe Haven Demand (real series): SPY 20-day return minus IEF 20-day return
rSPY = not na(mktD) and not na(mktD[fgRetLen]) and mktD[fgRetLen] != 0 ? mktD / mktD[fgRetLen] - 1 : na
fgR7 = not na(rSPY) and not na(rIEF) ? rSPY - rIEF : na
fgS7 = 100 * fgPhi(fgZScore(fgR7))

fgWSum = fgW1 + fgW2 + fgW3 + fgW4 + fgW5 + fgW6 + fgW7
fgGauge = fgWSum > 0 ? (fgW1 * fgS1 + fgW2 * fgS2 + fgW3 * fgS3 + fgW4 * fgS4 + fgW5 * fgS5 + fgW6 * fgS6 + fgW7 * fgS7) / fgWSum : 50.0
fgExtFear = fgGauge <= fgFear
fgExtGreed = fgGauge >= fgGreed
fgZoneTxt = fgExtFear ? "EXTREME FEAR" : fgExtGreed ? "EXTREME GREED" : fgGauge < 45 ? "FEAR" : fgGauge > 55 ? "GREED" : "NEUTRAL"

// ── Higher-timeframe alignment gate (non-repainting, backtest winner) ──
// HTF EMA21/EMA50 on the HTF chart's own closes, lookahead OFF: a bar only
// ever sees HTF values from fully confirmed HTF bars. Walk-forward PASS:
// V1 beat the shipped baseline on PF and expectancy in all 5 folds.
useHTFAlign = input.bool(true, "Require Higher-Timeframe Alignment", group=GRP_SG)
alignTF = input.timeframe("W", "Alignment Timeframe", group=GRP_SG)
alignClose = request.security(syminfo.tickerid, alignTF, close, lookahead=barmerge.lookahead_off)
alignEmaFast = ta.ema(alignClose, 21)
alignEmaSlow = ta.ema(alignClose, 50)
alignBull = not na(alignEmaFast) and not na(alignEmaSlow) and alignEmaFast > alignEmaSlow
alignBear = not na(alignEmaFast) and not na(alignEmaSlow) and alignEmaFast < alignEmaSlow
alignLongOK = not useHTFAlign or alignBull
alignShortOK = not useHTFAlign or alignBear

longGate = bullReg and not rangeReg and volOK and rsLongOK and betaLongOK and volatilityOK and notChasing and srBull and k < stochLongMax and alignLongOK
shortGate = bearReg and not rangeReg and volOK and rsShortOK and volatilityOK and notChasing and srBear and k > stochShortMin and not longOnly and alignShortOK
rawLong = scoreSafe >= longThresh and longGate
rawShort = scoreSafe <= -shortThresh and shortGate
var int lastSignalBar = na
cooldownOK = na(lastSignalBar) or bar_index - lastSignalBar > cooldownBars
newLong = barstate.isconfirmed and rawLong and not rawLong[1] and cooldownOK
newShort = barstate.isconfirmed and rawShort and not rawShort[1] and cooldownOK
if newLong or newShort
    lastSignalBar := bar_index

// ── Fear/Greed conviction ──
// FG1 (optional, tested neutral): at contrarian extremes a signal scoring
// within 1 point of strong is treated as strong sooner.
fgConvLong = useFGConv and newLong and fgExtFear and scoreSafe >= longThresh + strongOffset - 1
fgConvShort = useFGConv and newShort and fgExtGreed and scoreSafe <= -(shortThresh + strongOffset - 1)
strongLong = newLong and (scoreSafe >= longThresh + strongOffset or fgConvLong)
strongShort = newShort and (scoreSafe <= -(shortThresh + strongOffset) or fgConvShort)
// FG2 (default ON, backtest winner): don't chase the crowd — no new longs in
// Extreme Greed and no new shorts in Extreme Fear unless the signal is strong.
fgBlockLong = useFGBlock and fgExtGreed and not strongLong
fgBlockShort = useFGBlock and fgExtFear and not strongShort
// VIX1 (default ON, backtest winner): longs only when VIX is calm. The panel
// folds KC3's panic-spike entry filter into the gated signal (same outcome as
// the strategy's order-layer check).
tradeLong = newLong and not fgBlockLong and (not useVIXCalm or vixCalm) and not vixPanic
tradeShort = newShort and not fgBlockShort and not vixPanic
tradeStrongLong = strongLong and (not useVIXCalm or vixCalm) and not vixPanic
tradeStrongShort = strongShort and not vixPanic

// ── Setup classification (drives the diamond tags) ──
priorHigh = ta.highest(high[1], breakoutLookback)
priorLow = ta.lowest(low[1], breakoutLookback)
breakoutLong = close > priorHigh and volStrong and atrRatio > 1.0 and bullReg
breakoutShort = close < priorLow and volStrong and atrRatio > 1.0 and bearReg
reversalLong = bullDiv and (wtBullCross or srBullCross) and close > emaFast
reversalShort = bearDiv and (wtBearCross or srBearCross) and close < emaFast
// NOTE: plotshape text must be a const string in Pine, so the tags below are
// separate const-text plotshape calls rather than one dynamic text= call.
isBO = (tradeLong and breakoutLong) or (tradeShort and breakoutShort)
isREV = (tradeLong and reversalLong) or (tradeShort and reversalShort)
isCONT = not isBO and not isREV
buySig = tradeLong and not tradeStrongLong
sellSig = tradeShort and not tradeStrongShort

// ── Chase-blocked: the score wanted a signal but price was too extended ──
longGateNoChase = bullReg and not rangeReg and volOK and rsLongOK and betaLongOK and volatilityOK and srBull and k < stochLongMax and alignLongOK
shortGateNoChase = bearReg and not rangeReg and volOK and rsShortOK and volatilityOK and srBear and k > stochShortMin and not longOnly and alignShortOK
rawLongNoChase = scoreSafe >= longThresh and longGateNoChase
rawShortNoChase = scoreSafe <= -shortThresh and shortGateNoChase
chaseBlockedLong = barstate.isconfirmed and rawLongNoChase and not rawLongNoChase[1] and cooldownOK and not rawLong
chaseBlockedShort = barstate.isconfirmed and rawShortNoChase and not rawShortNoChase[1] and cooldownOK and not rawShort

// ── Score histogram ──
scoreCol = scoreSafe >= longThresh ? color.new(#00e5a0, 10) : scoreSafe <= -shortThresh ? color.new(#ff4d6d, 10) : color.new(#8a8f98, 45)
plot(scoreSafe, "Confluence Score", style=plot.style_columns, color=scoreCol)
hline(longThresh, "Long Trigger", color.new(#00e5a0, 50), hline.style_dashed)
hline(-shortThresh, "Short Trigger", color.new(#ff4d6d, 50), hline.style_dashed)
hline(0, "Zero", color.new(#ffffff, 85), hline.style_solid)

// ── Fear/Greed gauge (own pane, same math as KC3) ──
buyCol = color.new(#00e5a0, 0)
sellCol = color.new(#ff4d6d, 0)
fgLineCol = fgExtGreed ? sellCol : fgExtFear ? buyCol : color.new(#e8ecf1, 10)
plot(useFG ? fgGauge : na, "QK Fear/Greed", fgLineCol, 2, display=display.pane)
fgHiP = plot(useFG ? fgGreed * 1.0 : na, "FG Greed Line", color.new(#ff4d6d, 60), display=display.pane)
fgLoP = plot(useFG ? fgFear * 1.0 : na, "FG Fear Line", color.new(#00e5a0, 60), display=display.pane)
fgMidP = plot(useFG ? 50.0 : na, "FG Neutral Line", color.new(#8a8f98, 80), display=display.pane)
fill(fgHiP, fgMidP, color.new(#ff4d6d, 92), "FG Greed Fill")
fill(fgMidP, fgLoP, color.new(#00e5a0, 92), "FG Fear Fill")

// ── Diamonds: green = BUY, red = SELL, large = STRONG ──
diaTxtC = color.new(#e8ecf1, 0)
plotshape(buySig and isBO ? -12.5 : na, "BUY · BO", shape.diamond, location.absolute, buyCol, size=size.small, text="BO", textcolor=diaTxtC)
plotshape(buySig and isREV ? -12.5 : na, "BUY · REV", shape.diamond, location.absolute, buyCol, size=size.small, text="REV", textcolor=diaTxtC)
plotshape(buySig and isCONT ? -12.5 : na, "BUY · CONT", shape.diamond, location.absolute, buyCol, size=size.small, text="CONT", textcolor=diaTxtC)
plotshape(tradeStrongLong and isBO ? -12.5 : na, "STRONG BUY · BO", shape.diamond, location.absolute, buyCol, size=size.large, text="BO", textcolor=diaTxtC)
plotshape(tradeStrongLong and isREV ? -12.5 : na, "STRONG BUY · REV", shape.diamond, location.absolute, buyCol, size=size.large, text="REV", textcolor=diaTxtC)
plotshape(tradeStrongLong and isCONT ? -12.5 : na, "STRONG BUY · CONT", shape.diamond, location.absolute, buyCol, size=size.large, text="CONT", textcolor=diaTxtC)
plotshape(sellSig and isBO ? 12.5 : na, "SELL · BO", shape.diamond, location.absolute, sellCol, size=size.small, text="BO", textcolor=diaTxtC)
plotshape(sellSig and isREV ? 12.5 : na, "SELL · REV", shape.diamond, location.absolute, sellCol, size=size.small, text="REV", textcolor=diaTxtC)
plotshape(sellSig and isCONT ? 12.5 : na, "SELL · CONT", shape.diamond, location.absolute, sellCol, size=size.small, text="CONT", textcolor=diaTxtC)
plotshape(tradeStrongShort and isBO ? 12.5 : na, "STRONG SELL · BO", shape.diamond, location.absolute, sellCol, size=size.large, text="BO", textcolor=diaTxtC)
plotshape(tradeStrongShort and isREV ? 12.5 : na, "STRONG SELL · REV", shape.diamond, location.absolute, sellCol, size=size.large, text="REV", textcolor=diaTxtC)
plotshape(tradeStrongShort and isCONT ? 12.5 : na, "STRONG SELL · CONT", shape.diamond, location.absolute, sellCol, size=size.large, text="CONT", textcolor=diaTxtC)

// ── Chase-blocked ghosts: the setup was there but price was too extended ──
plotshape(chaseBlockedLong ? -12.5 : na, "Chase-blocked Long", shape.diamond, location.absolute, color.new(#8a8f98, 45), size=size.small, text="EXT", textcolor=color.new(#8a8f98, 0))
plotshape(chaseBlockedShort ? 12.5 : na, "Chase-blocked Short", shape.diamond, location.absolute, color.new(#8a8f98, 45), size=size.small, text="EXT", textcolor=color.new(#8a8f98, 0))

// ── VOLUME STRIP (pinned to LEFT edge of pane) ──
hotLevel = volBaseline * volumeSurgeLevel
volNorm = hotLevel > 0 ? nz(volume, 0) / hotLevel * 10 : 0
volHot = nz(volume, 0) >= hotLevel
// Median bar duration every bar (robust to weekend/holiday gaps);
// ta.* calls must stay at global scope to keep their history.
barDurRaw = time - time[1]
stripBarDur = int(nz(ta.median(barDurRaw, math.min(volStripBars, 100)), 0))

var array<box> volBoxes = array.new<box>()
var line volRefLine = na

if barstate.islast
    while array.size(volBoxes) > 0
        box.delete(array.pop(volBoxes))
    line.delete(volRefLine)
    volRefLine := na
    if showVolStrip
        barDur = stripBarDur
        leftT = chart.left_visible_bar_time
        n = math.min(volStripBars, bar_index + 1)
        if barDur > 0 and not na(leftT) and n > 0
            for i = 0 to n - 1
                // Chronological: oldest bar at the left edge, newest at the right.
                idx = n - 1 - i
                v = nz(volNorm[idx], 0)
                isHot = volHot[idx]
                x1 = int(leftT + i * barDur)
                x2 = int(leftT + (i + 0.8) * barDur)
                c = isHot ? color.new(#ffd60a, 5) : color.new(#5b6b8c, 55)
                array.push(volBoxes, box.new(x1, v, x2, 0, xloc=xloc.bar_time, border_color=c, bgcolor=c))
            volRefLine := line.new(int(leftT), 10, int(leftT + n * barDur), 10, xloc=xloc.bar_time, color=color.new(#ffd60a, 35), style=line.style_dashed, width=1)

// ── Numeric score label, top-right of the panel ──
var label scoreLbl = na
if barstate.islast
    label.delete(scoreLbl)
    scoreLblCol = scoreSafe >= longThresh ? color.new(#00e5a0, 15) : scoreSafe <= -shortThresh ? color.new(#ff4d6d, 15) : color.new(#8a8f98, 15)
    scoreLbl := label.new(bar_index, 13.2, "Score " + str.tostring(scoreSafe) + (useFG ? " · FG " + str.tostring(fgGauge, "#") + " " + fgZoneTxt : ""), style=label.style_label_down, color=scoreLblCol, textcolor=color.new(#ffffff, 0), size=size.small)

// ── CONTRACT STRIP (fine print, bottom-left) ──
// The decision contract: last signal, score vs trigger, live gate state.
// Brief by design — three rows, tiny text, out of the way.
var string cSig = "—"
var string cSetup = ""
var int cSigBar = na
if tradeStrongLong or tradeLong
    cSig := tradeStrongLong ? "STRONG BUY" : "BUY"
    cSetup := isBO ? "BO" : isREV ? "REV" : "CONT"
    cSigBar := bar_index
if tradeStrongShort or tradeShort
    cSig := tradeStrongShort ? "STRONG SELL" : "SELL"
    cSetup := isBO ? "BO" : isREV ? "REV" : "CONT"
    cSigBar := bar_index
cAge = na(cSigBar) ? "" : " · " + str.tostring(bar_index - cSigBar) + " bars ago"
fgZ = fgExtGreed ? "X-GREED" : fgExtFear ? "X-FEAR" : fgGauge < 45 ? "FEAR" : fgGauge > 55 ? "GREED" : "NEUT"
gateTxt = (useFG ? "FG " + str.tostring(fgGauge, "#") + " " + fgZ + " " + (fgBlockLong or fgBlockShort ? "✗BLOCK" : "✓") : "FG off") + " · " + (vixPanic ? "VIX PANIC ✗" : useVIXCalm ? (vixCalm ? "VIX calm ✓" : "VIX high ✗") : "VIX off") + " · HTF " + (alignBull ? "bull ✓" : alignBear ? "bear ✓" : "—")

// ── Gate diagnostic: what's blocking a signal right now, failures only ──
dirUpD = bullReg or not bearReg
gRegime = dirUpD ? bullReg : bearReg
gScoreD = dirUpD ? scoreSafe >= longThresh : scoreSafe <= -shortThresh
gRvolD = volOK
gRSD = dirUpD ? rsLongOK : rsShortOK
gBetaD = dirUpD ? betaLongOK : true
gAtrD = volatilityOK
gChaseD = notChasing
gStochD = dirUpD ? (srBull and k < stochLongMax) : (srBear and k > stochShortMin)
gFGD = not (dirUpD ? fgBlockLong : fgBlockShort)
gVixD = not vixPanic and (not useVIXCalm or not dirUpD or vixCalm)
gHTFD = dirUpD ? alignLongOK : alignShortOK
gCoolD = cooldownOK
blkTxt = (gRegime ? "" : "REGIME ") + (gScoreD ? "" : "SCORE ") + (gRvolD ? "" : "RVOL ") + (gRSD ? "" : "RS ") + (gBetaD ? "" : "BETA ") + (gAtrD ? "" : "ATR ") + (gChaseD ? "" : "CHASE ") + (gStochD ? "" : "STOCH ") + (gFGD ? "" : "FG ") + (gVixD ? "" : "VIX ") + (gHTFD ? "" : "HTF ") + (gCoolD ? "" : "COOL ")
blkTxt := blkTxt == "" ? "all pass ✓" : "BLOCKED: " + blkTxt

var table contract = table.new(position.bottom_left, 2, 4, border_width=1, border_color=color.new(#ffffff, 88))
wcAge = na(wcBar) ? "" : " · WHITE " + str.tostring(bar_index - wcBar) + "b ago"
bcAge = na(bcBar) ? "" : " · BLACK " + str.tostring(bar_index - bcBar) + "b ago"
if barstate.islast and showContract
    sigBull = str.contains(cSig, "BUY")
    sigBear = str.contains(cSig, "SELL")
    sigBg = sigBull ? color.new(#00e5a0, 80) : sigBear ? color.new(#ff4d6d, 80) : color.new(#8a8f98, 80)
    table.cell(contract, 0, 0, "KC2 · " + syminfo.ticker + " · " + timeframe.period, text_color=color.new(#8a8f98, 0), text_size=size.tiny)
    table.cell(contract, 1, 0, "SCORE " + (scoreSafe > 0 ? "+" : "") + str.tostring(scoreSafe) + "/" + str.tostring(scoreSafe >= 0 ? longThresh : shortThresh), text_color=color.new(#e8ecf1, 0), text_size=size.tiny)
    table.cell(contract, 0, 1, "Signal", text_color=color.new(#8a8f98, 0), text_size=size.tiny)
    table.cell(contract, 1, 1, cSig + (cSetup != "" ? " · " + cSetup : "") + cAge + wcAge + bcAge, bgcolor=sigBg, text_color=color.new(#e8ecf1, 0), text_size=size.tiny)
    table.cell(contract, 0, 2, "Gates", text_color=color.new(#8a8f98, 0), text_size=size.tiny)
    table.cell(contract, 1, 2, gateTxt, text_color=color.new(#e8ecf1, 0), text_size=size.tiny)
    table.cell(contract, 0, 3, "Signal check", text_color=color.new(#8a8f98, 0), text_size=size.tiny)
    table.cell(contract, 1, 3, blkTxt, bgcolor=str.contains(blkTxt, "BLOCKED") ? color.new(#ff4d6d, 80) : color.new(#00e5a0, 80), text_color=color.new(#e8ecf1, 0), text_size=size.tiny)

// ── Alerts (one shot per signal) ──
alertcondition(tradeLong, "KC2 Long", "KC2 LONG on {{ticker}} ({{interval}}) at {{close}}")
alertcondition(tradeShort, "KC2 Short", "KC2 SHORT on {{ticker}} ({{interval}}) at {{close}}")
alertcondition(tradeStrongLong, "KC2 Strong Long", "KC2 STRONG LONG on {{ticker}} ({{interval}}) at {{close}}")
alertcondition(tradeStrongShort, "KC2 Strong Short", "KC2 STRONG SHORT on {{ticker}} ({{interval}}) at {{close}}")
alertcondition(whiteCandle, "KC2 White Candle", "KC2 WHITE CANDLE on {{ticker}} ({{interval}}) at {{close}}")
alertcondition(blackCandle, "KC2 Black Candle", "KC2 BLACK CANDLE on {{ticker}} ({{interval}}) at {{close}}")

Overview

Kernal Cipher 2 scores trend with fast, slow, and long EMAs, slope, Supertrend, and ADX, then blends WaveTrend, StochRSI, pivot divergence, volume, relative strength versus equity benchmarks, and beta. Green and red diamonds mark buys and sells; larger marks mean stronger confluence and tags show breakout, continuation, or reversal. Hollow gray diamonds mark signals blocked by the anti-chase filter. A histogram plots the confluence score and a left-edge strip marks volume surges. Fear/greed and VIX gates can suppress signals. Settings change lengths, thresholds, and filters.

Details

Published by

kdricha0602 on GitHub

Draws

Separate pane below the chart

Markets

Stocks, Indices

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Topics

pine-scripttechnical-analysistradingtradingview-pro-2026

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
EMA Fastint21emaFastLen
EMA Slowint50emaSlowLen
EMA Long / Regimeint200emaLongLen
EMA Slope Lookbackint5slopeLen
Minimum EMA Slope %float0.05minSlopePct
ATR Lengthint10stLen
Multiplierfloat3.0stMult
ADX Lengthint14adxLen
ADX Minimumint20adxThresh
Require DI AlignmentbooltruerequireDiAlignment
Channel Lengthint10wtN1
Average Lengthint21wtN2
Show all 40 settings
SettingTypeDefaultVariable
RSI Lengthint14rsiLen
Stochastic Lengthint14stochLen
Smooth Kint3smoothK
Smooth Dint3smoothD
Maximum K for Long Entryfloat80stochLongMax
Minimum K for Short Entryfloat20stochShortMin
Pivot Lookback Leftint5lbL
Pivot Lookback Rightint5lbR
Min Bars Between Pivotsint5divMinBars
Max Bars Between Pivotsint60divMaxBars
Use Relative Strength FilterbooltrueuseRSFilter
Primary BenchmarksymbolAMEX:SPYbench1
Secondary BenchmarksymbolNASDAQ:QQQbench2
RS Lookbackint20rsLen
Minimum RS % for Longsfloat0.0rsLongMin
Maximum RS % for Shortsfloat0.0rsShortMax
Beta Lookbackint60betaLen
Minimum Beta for Longsfloat0.7betaMin
Require Minimum Beta for LongsboolfalseuseBetaFilter
ATR Lengthint14atrLen
ATR Stop Multiplierfloat2.0atrStopMult
ATR Regime Baselineint50atrRegimeLen
Min ATR / ATR Baselinefloat0.80atrExpansionMin
Max ATR / ATR Baselinefloat3.00atrExpansionMax
Max Distance From Fast EMA (ATR)float1.5maxChaseATR
Volume Baseline Lengthint20volLen
Minimum RVOLfloat1.20rvolMin
Strong RVOLfloat2.00rvolStrong
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

9 stars

FlowBias calculates a composite market momentum metric using Chaikin Money Flow, volume delta, Stochastic, and the Ultimate Oscillator. Plotted in a separate pane, it identifies trend pullbacks and market exhaustion reversals through visual signals and labels.

Indicator v6 TrendOscillators & momentum
Updated 3 days ago · MIT GitHub repository of FlowBias [WavesUnchained]
1 stars

This indicator calculates a multi-factor trend and momentum score by combining triple exponential moving averages, Supertrend, ADX regime filters, WaveTrend, and StochRSI oscillators. It identifies regular divergences across pivot points, checks multi-timefram

Indicator v6 TrendOscillators & momentum
Updated 5 weeks ago · MIT GitHub repository of Momentum Confluence Suite [MCS] v2

Oscillator Suite

by TamaraKGreen
46 stars

Oscillator Suite plots a normalised price oscillator in a separate pane and overlays a signal line that can use SMA, EMA, WMA, HMA, RMA, VWMA, T3, ZEMA, KAMA, or GKEMA. It marks bullish and bearish divergences, a smoothed money-flow series, confluence areas an

Indicator v5 Oscillators & momentumDivergence
Updated 8 weeks ago · None stated GitHub repository of Oscillator Suite

MFI Divergences

by tistaharahap
25 stars

This indicator plots the Money Flow Index in a separate pane and marks regular and hidden bullish and bearish divergences between price pivots and the oscillator. It builds the index from positive and negative money flow, then finds pivot highs and lows using

Indicator v4 Oscillators & momentumVolume
Updated 6 years ago · None stated GitHub repository of MFI Divergences
11 stars

This indicator plots a smoothed Z-score of cumulative volume delta in a separate pane, showing whether buying or selling pressure is dominant and when the reading enters extreme zones. It marks spot accumulation, climax or exhaustion, and pivot-based price-vol

Indicator v6 Oscillators & momentumVolume Repaints
Updated 7 weeks ago · MIT GitHub repository of CVD Z-Score [NeuNue]

DC-B v2.5

by crissrocca
9 stars

This indicator is an oscillator suite inspired by Market Cipher B and VuManChu Cipher B that plots in a separate pane. It combines a WaveTrend oscillator, a Money Flow Index (MFI) area, and an RSI indicator with automatic divergence detection. Visual signals h

Indicator v4 Oscillators & momentumDivergence
Updated 3 years ago · MPL-2.0 GitHub repository of DC-B v2.5

More Trend scripts

Related on ForexR

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers