# antwerks enhanced 12/14/2025
declare lower;
#------------------ Inputs ------------------
input priceLength = 5; # lookback for price ROC (Delta proxy)
input ivLength = 5; # lookback for IV ROC (Gamma proxy)
input smooth = 3; # smoothing of divergence
input extremeLookback = 20; # window for "extreme" pivots
input showBubbles = yes; # value bubbles at extremes
input showArrows = yes; # arrows at extremes
input bandMult = 2.0; # threshold band multiplier (std dev)
input maLength = 20; # moving average for price action label
input tradeSignalMA = 10; # MA for trade signal integration
#------------------ Manual ROC Definitions ------------------
def priceROC = if close[priceLength] != 0
then (close - close[priceLength]) / close[priceLength] * 100
else 0;
def iv = imp_volatility();
def ivROC = if iv[ivLength] != 0
then (iv - iv[ivLength]) / iv[ivLength] * 100
else 0;
#------------------ Divergence ------------------
def rawDiv = ivROC - priceROC;
def osc = Average(rawDiv, smooth);
#------------------ Threshold Bands ------------------
def oscMean = Average(osc, extremeLookback);
def oscStd = StDev(osc, extremeLookback);
def upperBandVal = oscMean + bandMult * oscStd;
def lowerBandVal = oscMean - bandMult * oscStd;
plot UpperBand = upperBandVal;
UpperBand.SetDefaultColor(Color.LIGHT_GRAY);
UpperBand.SetStyle(Curve.SHORT_DASH);
plot LowerBand = lowerBandVal;
LowerBand.SetDefaultColor(Color.LIGHT_GRAY);
LowerBand.SetStyle(Curve.SHORT_DASH);
#------------------ Plots --------------------
plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.GRAY);
plot Oscillator = osc;
Oscillator.AssignValueColor(
if osc > upperBandVal then Color.CYAN
else if osc < lowerBandVal then Color.MAGENTA
else if osc > 0 then Color.GREEN
else Color.RED);
Oscillator.SetLineWeight(2);
plot Hist = osc;
Hist.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Hist.AssignValueColor(
if osc > upperBandVal then Color.CYAN
else if osc < lowerBandVal then Color.MAGENTA
else if osc > 0 then Color.DARK_GREEN
else Color.DARK_RED);
Hist.SetLineWeight(3);
#------------------ Extreme Pivots ------------------
def hiN = Highest(osc, extremeLookback);
def loN = Lowest(osc, extremeLookback);
def newHigh = osc == hiN and osc[1] < hiN[1];
def newLow = osc == loN and osc[1] > loN[1];
plot HighArrow = if showArrows and newHigh then osc else Double.NaN;
HighArrow.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
HighArrow.SetLineWeight(3);
HighArrow.SetDefaultColor(Color.RED);
plot LowArrow = if showArrows and newLow then osc else Double.NaN;
LowArrow.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
LowArrow.SetLineWeight(3);
LowArrow.SetDefaultColor(Color.GREEN);
AddChartBubble(showBubbles and newHigh, osc,
"New " + extremeLookback + "-bar HIGH\n" + Round(osc, 2),
Color.RED, yes);
AddChartBubble(showBubbles and newLow, osc,
"New " + extremeLookback + "-bar LOW\n" + Round(osc, 2),
Color.GREEN, no);
#------------------ Alerts ------------------
Alert(osc crosses above 0, "Oscillator crossed above zero", Alert.BAR, Sound.Ring);
Alert(osc crosses below 0, "Oscillator crossed below zero", Alert.BAR, Sound.Bell);
Alert(osc crosses above upperBandVal, "Oscillator crossed above upper band", Alert.BAR, Sound.Chimes);
Alert(osc crosses below lowerBandVal, "Oscillator crossed below lower band", Alert.BAR, Sound.Ding);
#------------------ Trade Signal Integration ------------------
def priceMA = Average(close, tradeSignalMA);
def tradeLong = osc crosses above 0 and close > priceMA;
def tradeShort = osc crosses below 0 and close < priceMA;
plot TradeLongSignal = if tradeLong then osc else Double.NaN;
TradeLongSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
TradeLongSignal.SetDefaultColor(Color.BLUE);
TradeLongSignal.SetLineWeight(4);
plot TradeShortSignal = if tradeShort then osc else Double.NaN;
TradeShortSignal.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
TradeShortSignal.SetDefaultColor(Color.ORANGE);
TradeShortSignal.SetLineWeight(4);
#------------------ Price Action Labels ------------------
def mainMA = Average(close, maLength);
def newHighPrice = close == Highest(close, extremeLookback);
def newLowPrice = close == Lowest(close, extremeLookback);
AddLabel(yes,
if newHighPrice then "Price: " + extremeLookback + "-bar High Breakout"
else if newLowPrice then "Price: " + extremeLookback + "-bar Low Breakdown"
else if close > mainMA then "Price Above " + maLength + "MA (Uptrend)"
else "Price Below " + maLength + "MA (Downtrend)",
if newHighPrice then Color.GREEN else if newLowPrice then Color.RED else if close > mainMA then Color.LIGHT_GREEN else Color.LIGHT_RED);
def fastMA = Average(close, 10);
def slowMA = Average(close, 30);
def trendUp = fastMA > slowMA;
def trendDown = fastMA < slowMA;
AddLabel(yes,
if trendUp then "TREND: Bullish"
else if trendDown then "TREND: Bearish"
else "TREND: Neutral",
if trendUp then Color.GREEN
else if trendDown then Color.RED
else Color.GRAY);
#------------------ Oscillator Regime Labels ------------------
def pctAboveZero = 100 * Average( if osc > 0 then 1 else 0, extremeLookback);
AddLabel(yes,
"Div %>0 (" + extremeLookback + "): " + AsPercent(pctAboveZero/100),
if pctAboveZero >= 70 then Color.GREEN
else if pctAboveZero <= 30 then Color.RED
else Color.YELLOW);
AddLabel(yes,
if osc > 0 then "Hedging Pressure UP (Vol Expansion Likely)"
else "Calmer Regime / Trend Continuation",
if osc > 0 then Color.GREEN else Color.RED);
#------------------ Trade Signal Labels ------------------
AddLabel(tradeLong, "Trade Signal: LONG", Color.BLUE);
AddLabel(tradeShort, "Trade Signal: SHORT", Color.ORANGE);
AddLabel(yes,
if osc > 0 and trendUp then "Market Bias: Bullish (Momentum + Trend)"
else if osc < 0 and trendDown then "Market Bias: Bearish (Momentum + Trend)"
else if osc > 0 then "Volatility Pressure ↑ (Watch for breakout)"
else "Neutral/Choppy",
if osc > 0 and trendUp then Color.GREEN
else if osc < 0 and trendDown then Color.RED
else Color.YELLOW);