, please fix //@version=6
indicator("VI Custom", shorttitle="VICustom", overlay=false)

// ==============================
// User Inputs
// ==============================
period         = input.int(14, title="Period", minval=2)
res            = input.timeframe("240", title="Primary Resolution", options=["Current", "1","2","3","5", "15", "30", "60", "240", "D", "W", "M"])
res2           = input.timeframe("240", title="Secondary Resolution", options=["Current","1","2","3", "5", "15", "30", "60", "240", "D", "W", "M"])
alertOffset    = input.float(0.15, title="Alert Vertical Offset", step=0.05)
diffThreshold  = input.float(0.4, title="VI+ / VI– Alert Threshold", step=0.05)
showAlerts     = input.bool(true, title="Show Alert Shapes")

// Alert shape selection for primary alerts
primaryUpShapeInput   = input.string("triangleup", title="Primary Up Alert Shape", options=["triangleup", "circle", "diamond"])
primaryDownShapeInput = input.string("triangledown", title="Primary Down Alert Shape", options=["triangledown", "circle", "diamond"])

primaryShape   = primaryUpShapeInput == "triangleup"   ? shape.triangleup   : primaryUpShapeInput == "circle" ? shape.circle   : shape.diamond
secondaryShape = primaryDownShapeInput == "triangledown" ? shape.triangledown : primaryDownShapeInput == "circle" ? shape.circle : shape.diamond

primaryRes   = res == "Current" ? timeframe.period : res
secondaryRes = res2 == "Current" ? timeframe.period : res2

// ==============================
// Vortex Calculation Function
// ==============================
f_vortex_calc(high, low, close) =>
    tr    = math.max(high - low, math.abs(high - close[1]), math.abs(low - high[1]))
    vmp   = math.abs(high - low[1])
    vmm   = math.abs(low - high[1])
    sum_tr  = ta.sma(tr, period)
    sum_vmp = ta.sma(vmp, period)
    sum_vmm = ta.sma(vmm, period)
    vip = sum_tr != 0 ? sum_vmp / sum_tr : na
    vim = sum_tr != 0 ? sum_vmm / sum_tr : na
    [vip, vim]

[vipValue, vimValue]     = request.security(syminfo.tickerid, primaryRes, f_vortex_calc(high, low, close), lookahead = barmerge.lookahead_off)
[vipValue2, vimValue2]   = request.security(syminfo.tickerid, secondaryRes, f_vortex_calc(high, low, close), lookahead = barmerge.lookahead_off)

crossOverPrimary    = ta.crossover(vipValue, vimValue)
crossUnderPrimary   = ta.crossunder(vipValue, vimValue)
crossOverSecondary  = ta.crossover(vipValue2, vimValue2)
crossUnderSecondary = ta.crossunder(vipValue2, vimValue2)

harmonyUp   = crossOverPrimary and crossOverSecondary
harmonyDown = crossUnderPrimary and crossUnderSecondary

plot(vipValue, title="VI+", color=color.blue, linewidth=2)
plot(vimValue, title="VI–", color=color.red, linewidth=2)

plotshape(showAlerts and crossOverPrimary ? vipValue + alertOffset : na, title="Primary Crossover", style=primaryShape, location=location.absolute, color=color.green, size=size.small)
plotshape(showAlerts and crossUnderPrimary ? vimValue - alertOffset : na, title="Primary Crossunder", style=secondaryShape, location=location.absolute, color=color.red, size=size.small)

plotshape(showAlerts and harmonyUp ? vipValue + (alertOffset * 2) : na, title="Harmony Up", style=shape.diamond, location=location.absolute, color=color.yellow, size=size.normal, offset=1)
plotshape(showAlerts and harmonyDown ? vimValue - (alertOffset * 2) : na, title="Harmony Down", style=shape.diamond, location=location.absolute, color=color.orange, size=size.normal, offset=1)

hline(1.0, title="Neutral", color=color.gray, linestyle=hline.style_dashed)
hline(1.1, title="Upper",   color=color.gray, linestyle=hline.style_dotted)
hline(0.9, title="Lower",   color=color.gray, linestyle=hline.style_dotted)

// ==============================
// Custom Alert: User-defined Difference Between VI+ and VI–
// ==============================
vipVimDiff = math.abs(vipValue - vimValue)
alertcondition(vipVimDiff > diffThreshold, title="VI+ / VI– Diff > Threshold", message="VI+ and VI– differ by more than your selected threshold")
alertcondition(crossOverPrimary, title="Primary VI+ Crossover", message="Primary VI+ crossed above VI–")
alertcondition(crossUnderPrimary, title="Primary VI+ Crossunder", message="Primary VI+ crossed below VI–")
alertcondition(harmonyUp, title="Harmony Up", message="Both timeframes show VI+ crossover")
alertcondition(harmonyDown, title="Harmony Down", message="Both timeframes show VI+ crossunder")

// ==============================
// Divergence Detection
// ==============================
left = 3
right = 3
vipHighPivot = ta.pivothigh(vipValue, left, right)
vipLowPivot  = ta.pivotlow(vipValue, left, right)
priceHighPivot = ta.pivothigh(high, left, right)
priceLowPivot  = ta.pivotlow(low, left, right)

bearDiv = not na(priceHighPivot) and not na(vipHighPivot) and priceHighPivot > priceHighPivot[1] and vipHighPivot < vipHighPivot[1]
bullDiv = not na(priceLowPivot) and not na(vipLowPivot) and priceLowPivot < priceLowPivot[1] and vipLowPivot > vipLowPivot[1]

if bearDiv
    line.new(x1=bar_index[right+1], y1=priceHighPivot[right+1], x2=bar_index, y2=priceHighPivot, color=color.red, width=2)
    line.new(x1=bar_index[right+1], y1=vipHighPivot[right+1], x2=bar_index, y2=vipHighPivot, color=color.red, width=2)
    label.new(x=bar_index, y=vipHighPivot, text="Bear Div", style=label.style_labeldown, color=color.red, textcolor=color.white)

if bullDiv
    line.new(x1=bar_index[right+1], y1=priceLowPivot[right+1], x2=bar_index, y2=priceLowPivot, color=color.green, width=2)
    line.new(x1=bar_index[right+1], y1=vipLowPivot[right+1], x2=bar_index, y2=vipLowPivot, color=color.green, width=2)
    label.new(x=bar_index, y=vipLowPivot, text="Bull Div", style=label.style_labelup, color=color.green, textcolor=color.white)

alertcondition(bearDiv, title="Bearish Divergence", message="Bearish divergence detected: Price makes higher high, VI+ makes lower high")
alertcondition(bullDiv, title="Bullish Divergence", message="Bullish divergence detected: Price makes lower low, VI+ makes higher low")