IPM Day Trading Buy/Sell Signals
Cut and Paste into ToS charts--From declare lower;



declare upper;

#==================================================
# 1. ZERO LAG BANDS & CLOUDS
#==================================================
input length = 70;
input mult = 1.2;

def srcPrice = close;
def lag = Floor((length - 1) / 2);
def zlemaSrc = srcPrice + (srcPrice - srcPrice[lag]);
def zlema = ExpAverage(zlemaSrc, length);

def currentATR = ATR(length, averageType = AverageType.WILDERS);
def volatility = Highest(currentATR, length * 3) * mult;

def crossUp = close crosses above zlema + volatility;
def crossDn = close crosses below zlema - volatility;
def trend = if crossUp then 1 else if crossDn then -1 else trend[1];

plot ZLEMA_Line = zlema;
ZLEMA_Line.SetLineWeight(2);
ZLEMA_Line.AssignValueColor(
    if trend == 1 then CreateColor(0, 255, 187)
    else CreateColor(255, 17, 0)
);

plot UpperBand = if trend == -1 then zlema + volatility else Double.NaN;
UpperBand.SetDefaultColor(CreateColor(255, 17, 0));
UpperBand.SetLineWeight(1);

plot LowerBand = if trend == 1 then zlema - volatility else Double.NaN;
LowerBand.SetDefaultColor(CreateColor(0, 255, 187));
LowerBand.SetLineWeight(1);

def midPrice = (open + close) / 2;
AddCloud(UpperBand, midPrice, CreateColor(150, 50, 50), CreateColor(150, 50, 50));
AddCloud(midPrice, LowerBand, CreateColor(50, 150, 100), CreateColor(50, 150, 100));

#==================================================
# 2. PPO MATH (BOOSTED)
#==================================================
input fastLen = 12;
input slowLen = 26;
input sigLen  = 9;
input ppoVisualBoost = 500;

def maFast = ExpAverage(close, fastLen);
def maSlow = ExpAverage(close, slowLen);
def rawPPO = 100 * (maFast - maSlow) / maSlow;

def PPO = rawPPO * ppoVisualBoost;
def PPO_Signal = ExpAverage(PPO, sigLen);
def Hist = PPO - PPO_Signal;

#==================================================
# 3. NORMAL PPO CROSS SIGNALS
#==================================================
plot BuySignal = if PPO crosses above PPO_Signal then low else Double.NaN;
BuySignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
BuySignal.SetDefaultColor(Color.GREEN);
BuySignal.SetLineWeight(4);

plot SellSignal = if PPO crosses below PPO_Signal then high else Double.NaN;
SellSignal.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
SellSignal.SetDefaultColor(Color.RED);
SellSignal.SetLineWeight(4);

#==================================================
# 4. DIVERGENCE (PRICE PIVOTS + HIST @ PIVOTS)
#==================================================
input pivotBars = 4;                 # cleaner swings
input useThresholdFilter = yes;      # only count pivots when momentum active
input divThreshold = 20.0;           # IMPORTANT: this is in *BOOSTED HIST units* (what you see)

# Centered price pivots (confirmed pivotBars bars later)
def pivH = high[pivotBars] == Highest(high, 2 * pivotBars + 1);
def pivL = low[pivotBars]  == Lowest(low,  2 * pivotBars + 1);

# Momentum filter at the pivot bar
def okHigh = if !useThresholdFilter then 1 else Hist[pivotBars] >  divThreshold;
def okLow  = if !useThresholdFilter then 1 else Hist[pivotBars] < -divThreshold;

def swingHigh = pivH and okHigh;
def swingLow  = pivL and okLow;

# Store last 2 swing highs + hist values at those swing highs
def pHigh1 = CompoundValue(1, if swingHigh then high[pivotBars] else pHigh1[1], Double.NaN);
def pHigh2 = CompoundValue(1, if swingHigh then pHigh1[1]        else pHigh2[1], Double.NaN);

def hHigh1 = CompoundValue(1, if swingHigh then Hist[pivotBars] else hHigh1[1], Double.NaN);
def hHigh2 = CompoundValue(1, if swingHigh then hHigh1[1]       else hHigh2[1], Double.NaN);

# Store last 2 swing lows + hist values at those swing lows
def pLow1 = CompoundValue(1, if swingLow then low[pivotBars] else pLow1[1], Double.NaN);
def pLow2 = CompoundValue(1, if swingLow then pLow1[1]       else pLow2[1], Double.NaN);

def hLow1 = CompoundValue(1, if swingLow then Hist[pivotBars] else hLow1[1], Double.NaN);
def hLow2 = CompoundValue(1, if swingLow then hLow1[1]        else hLow2[1], Double.NaN);

def have2Highs = !IsNaN(pHigh2) and !IsNaN(hHigh2);
def have2Lows  = !IsNaN(pLow2)  and !IsNaN(hLow2);

# Bearish divergence: price higher high, hist lower high
def bearishDiv = have2Highs and pHigh1 > pHigh2 and hHigh1 < hHigh2;

# Bullish divergence: price lower low, hist higher low
def bullishDiv = have2Lows and pLow1 < pLow2 and hLow1 > hLow2;

def bearFire = bearishDiv and !bearishDiv[1];
def bullFire = bullishDiv and !bullishDiv[1];

plot BearDivArrow = if bearFire then high + TickSize() * 15 else Double.NaN;
BearDivArrow.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
BearDivArrow.SetDefaultColor(Color.WHITE);
BearDivArrow.SetLineWeight(5);

plot BullDivArrow = if bullFire then low - TickSize() * 15 else Double.NaN;
BullDivArrow.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
BullDivArrow.SetDefaultColor(Color.WHITE);
BullDivArrow.SetLineWeight(5);