#// This source code is subject to the terms of the Mozilla Publi
#// © Beardy_Fred
#indicator('Beardy Squeeze Pro', shorttitle='Squeeze', overlay=false, precision=2)
# Converted and mod By Sam4Cok@Samer800 - 10 / 2023
# Update - Added Divergences - 08/2024
declare lower;
input enabelAlerts = yes;
input alertSound = {default "NoSound", "Ding", "Bell", "Chimes", "Ring"};
input alertType = Alert.BAR;
input showLabel = yes;
input colorBars = {Default "On Squeeze", "On Momentum", "Don't Color Bars"};
input movAvgType = AverageType.SIMPLE;
input source = close;
input length = 20;#, "TTM Squeeze Length")
input threshold = 1.0;
input BB_mult = 2.0;#, "Bollinger Band STD Multiplier")
input KC_mult_high = 1.0;#, "Keltner Channel #1")
input KC_mult_mid = 1.5;#, "Keltner Channel #2")
input KC_mult_low = 2.0;#, "Keltner Channel #3")
def na = Double.NaN;
def last = isNaN(close);
def pos = Double.POSITIVE_INFINITY;
def neg = Double.NEGATIVE_INFINITY;
def sqzBar = colorBars==colorBars."On Squeeze";
def momBar = colorBars==colorBars."On Momentum";
#--Colors
DefineGlobalColor("upGrow", CreateColor(0,188,212));
DefineGlobalColor("upFall", CreateColor(41,98,255));
DefineGlobalColor("dnGrow", CreateColor(255,235,59));
DefineGlobalColor("dnFall", CreateColor(255,82,82));
DefineGlobalColor("noSq", CreateColor(76,175,80));
DefineGlobalColor("loSq", Color.DARK_GRAY); #Color.GRAY);#CreateColor(54,58,69));
DefineGlobalColor("hiSq", Color.MAGENTA); #Color.RED); #CreateColor(255,82,82));
DefineGlobalColor("midSq",Color.PLUM); #CreateColor(255,152,0));
#//BOLLINGER BANDS
def BB_basis = MovingAverage(movAvgType, source, length);
def dev = BB_mult * StDev(source, length);
def BB_upper = BB_basis + dev;
def BB_lower = BB_basis - dev;
#//KELTNER CHANNELS
def KC_basis = BB_basis;#ta.sma(close, length)
def tr = TrueRange(high, close, low);
def devKC = MovingAverage(movAvgType, tr, length);
def KC_upper_high = KC_basis + devKC * KC_mult_high;
def KC_lower_high = KC_basis - devKC * KC_mult_high;
def KC_upper_mid = KC_basis + devKC * KC_mult_mid;
def KC_lower_mid = KC_basis - devKC * KC_mult_mid;
def KC_upper_low = KC_basis + devKC * KC_mult_low;
def KC_lower_low = KC_basis - devKC * KC_mult_low;
#//SQUEEZE CONDITIONS
def NoSqz = BB_lower < KC_lower_low or BB_upper > KC_upper_low; # //NO SQUEEZE: GREEN
def LowSqz = BB_lower >= KC_lower_low or BB_upper <= KC_upper_low; # //LOW COMPRESSION: BLACK
def MidSqz = BB_lower >= KC_lower_mid or BB_upper <= KC_upper_mid; # //MID COMPRESSION: RED
def HighSqz = BB_lower >= KC_lower_high or BB_upper <= KC_upper_high; # //HIGH COMPRESSION: ORANGE
#//MOMENTUM OSCILLATOR
def hh = Highest(high, length);
def ll = Lowest(low, length);
def hlAvg = (hh + ll + KC_basis) / 3;
def mom = Inertia(source - hlAvg, length);
#//MOMENTUM HISTOGRAM COLOR
def mom_col = if mom > 0 then
if mom > mom[1] then 2 else 1 else
if mom > mom[1] then -2 else - 1;
#//SQUEEZE DOTS COLOR
def sq_col = if HighSqz then 3 else
if MidSqz then 2 else
if LowSqz then 1 else 0;
#//PLOTS
plot sqLine = if last then na else 0; # 'SQZ'
plot momHist = mom; # 'MOM'
sqLine.SetLineWeight(2);
sqLine.SetPaintingStrategy(paintingStrategy.POINTS);
sqLine.AssignValueColor(if sq_col==3 then GlobalColor("hiSq") else
if sq_col==2 then GlobalColor("midSq") else
if sq_col==1 then GlobalColor("loSq") else GlobalColor("noSq"));
momHist.SetPaintingStrategy(paintingStrategy.SQUARED_HISTOGRAM);
momHist.AssignValueColor(if mom_col== 2 then GlobalColor("upGrow") else
if mom_col== 1 then GlobalColor("upFall") else
if mom_col==-2 then GlobalColor("dnGrow") else GlobalColor("dnFall"));
#-- Label
AddLabel(showLabel and sq_col==3, "HIGH COMPRESSION", GlobalColor("hiSq"));
AddLabel(showLabel and sq_col==2, "MID COMPRESSION", GlobalColor("midSq"));
AddLabel(showLabel and sq_col==1, "LOW COMPRESSION", GlobalColor("loSq"));
AddLabel(showLabel and sq_col==0, "NO SQUEEZE", GlobalColor("noSq"));
#-- Bar Color
AssignPriceColor(if !momBar then Color.CURRENT else
if mom_col== 2 then GlobalColor("upGrow") else
if mom_col== 1 then GlobalColor("upFall") else
if mom_col==-2 then GlobalColor("dnGrow") else GlobalColor("dnFall"));
AssignPriceColor(if !sqzBar then Color.CURRENT else
if sq_col==3 then GlobalColor("hiSq") else
if sq_col==2 then GlobalColor("midSq") else
if sq_col==1 then GlobalColor("loSq") else GlobalColor("noSq"));
AddCloud(if mom>= threshold then pos else na, neg, Color.DARK_GREEN);
AddCloud(if mom<=-threshold then pos else na, neg, Color.DARK_RED);
#-- END of CODE
#----Div-----------
input showDivergences = yes;
input LookBackRight = 5; # "Pivot Lookback Right"
input LookBackLeft = 5; # "Pivot Lookback Left"
input MaxLookback = 60; # "Max of Lookback Range"
input MinLookback = 5; # "Min of Lookback Range"
def divSrc = mom;
def h = high;
def l = low;
Script Pivot {
input series = close;
input leftBars = 10;
input rightBars = 10;
input isHigh = yes;
def na = Double.NaN;
def HH = series == Highest(series, leftBars + 1);
def LL = series == Lowest(series, leftBars + 1);
def pivotRange = (leftBars + rightBars + 1);
def leftEdgeValue = if series[pivotRange] ==0 then na else series[pivotRange];
def pvtCond = !isNaN(series) and leftBars > 0 and rightBars > 0 and !isNaN(leftEdgeValue);
def barIndexH = if pvtCond then
fold i = 1 to rightBars + 1 with p=1 while p do
series > GetValue(series, - i) else na;
def barIndexL = if pvtCond then
fold j = 1 to rightBars + 1 with q=1 while q do
series < GetValue(series, - j) else na;
def PivotPoint;
if isHigh {
PivotPoint = if HH and barIndexH then series else na;
} else {
PivotPoint = if LL and barIndexL then series else na;
}
plot pvt = PivotPoint;
}
#_inRange(cond) =>
script _inRange {
input cond = yes;
input rangeUpper = 60;
input rangeLower = 5;
def bars = if cond then 0 else bars[1] + 1;
def inrange = (rangeLower <= bars) and (bars <= rangeUpper);
plot retrun = inRange;
}
def pl_ = pivot(divSrc,LookBackLeft, LookBackRight, no);
def ph_ = pivot(divSrc,LookBackLeft, LookBackRight, yes);
def pl = !isNaN(pl_);
def ph = !isNaN(ph_);
def pll = lowest(divSrc,LookBackLeft +1);
def phh = highest(divSrc,LookBackLeft+1);
def sll = lowest(l, LookBackLeft +1);
def shh = highest(h, LookBackLeft+1);
#-- Pvt Low
def plStart = if pl then yes else plStart[1];
def plFound = if (plStart and pl) then 1 else 0;
def vlFound1 = if plFound then divSrc else vlFound1[1];
def vlFound_ = if vlFound1!=vlFound1[1] then vlFound1[1] else vlFound_[1];
def vlFound = if !vlFound_ then pll else vlFound_;
def plPrice1 = if plFound then l else plPrice1[1];
def plPrice_ = if plPrice1!=plPrice1[1] then plPrice1[1] else plPrice_[1];
def plPrice = if !plPrice_ then sll else plPrice_;
#-- Pvt High
def phStart = if ph then yes else phStart[1];
def phFound = if (phStart and ph) then 1 else 0;
def vhFound1 = if phFound then divSrc else vhFound1[1];
def vhFound_ = if vhFound1!=vhFound1[1] then vhFound1[1] else vhFound_[1];
def vhFound = if !vhFound_ then phh else vhFound_;
def phPrice1 = if phFound then h else phPrice1[1];
def phPrice_ = if phPrice1!=phPrice1[1] then phPrice1[1] else phPrice_[1];
def phPrice = if !phPrice_ then shh else phPrice_;
#// Regular Bullish
def inRangePl = _inRange(plFound[1],MaxLookback,MinLookback);
def oscHL = divSrc > vlFound and inRangePl;
def priceLL = l < plPrice and divSrc < 0;
def bullCond = plFound and oscHL and priceLL;
#// Regular Bearish
def inRangePh = _inRange(phFound[1],MaxLookback,MinLookback);
def oscLH = divSrc < vhFound and inRangePh;
def priceHH = h > phPrice and divSrc > 0;
def bearCond = phFound and oscLH and priceHH;
#------ Bubbles
def bullBub = showDivergences and bullCond;
def bearBub = showDivergences and bearCond;
addchartbubble(bullBub, divSrc, "R", Color.GREEN, no);
addchartbubble(bearBub, divSrc, "R", Color.RED, yes);
##### Lines
def bar = BarNumber();
#-- Bear Line
def lastPhBar = if ph then bar else lastPhBar[1];
def prePhBar = if lastPhBar!=lastPhBar[1] then lastPhBar[1] else prePhBar[1];
def priorPHBar = if bearCond then prePhBar else priorPHBar[1];
#-- Bull Line
def lastPlBar = if pl then bar else lastPlBar[1];
def prePlBar = if lastPlBar!=lastPlBar[1] then lastPlBar[1] else prePlBar[1];
def priorPLBar = if bullCond then prePlBar else priorPLBar[1];
def lastBullBar = if bullCond then bar else lastBullBar[1];
def lastBearBar = if bearCond then bar else lastBearBar[1];
def HighPivots = ph and bar >= HighestAll(priorPHBar) and bar <= HighestAll(lastBearBar);
def LowPivots = pl and bar >= HighestAll(priorPLBar) and bar <= HighestAll(lastBullBar);
def pivotHigh = if HighPivots then divSrc else na;
def pivotLow = if LowPivots then divSrc else na;
plot PlotHline = if showDivergences then pivotHigh else na;
PlotHline.EnableApproximation();
PlotHline.SetDefaultColor(Color.RED);
plot PlotLline = if showDivergences then pivotLow else na;
PlotLline.EnableApproximation();
PlotLline.SetDefaultColor(Color.GREEN);
#---- Alerts
Alert(enabelAlerts and bullCond, "Bullish Div", alertType, alertSound);
Alert(enabelAlerts and bearCond, "Bearish Div", alertType, alertSound);
#-- END of CODE