Option to show enclosing BB with Divergences.
You can trade this like any other oscillator -- 80/20 OB/OS levels, divergences, ...
CODE:
CSS:
#// @author LazyBear
#https://www.tradingview.com/script/pgvRuoUi-Firefly-Oscillator-LazyBear/
#// Original idea from a public Amibroker indicator published by @Yasu
#study(title = "Firefly Oscillator [LazyBear]", shorttitle="FIREFLY_LB")
# Created and mod by Sam4Cok@Samer800 - 10/2022
declare lower;
input Length = 10; # "Lookback Length"
input Smoothing = 3; # "Signal Smoothing"
input DoubleSmooth = no; # "Double smooth Osc"
input UseZLEMA = no; # "Use ZLEMA"
input ShowBB = no; # "Show Enclosing BB"
input bbLength = 20; # "Enclosing BB Length"
input bbMulti = 2.0; # "Enclosing BB Multiplier"
input bbBreaches = yes; # "Highlight Breaches"
input barColors = no; # "Enable bar colors"
input PivotLookback = 5; # "Pivot Lookback Right"
input DivBull = yes; # "Plot Bullish"
input DivHiddenBull = no; # "Plot Hidden Bullish"
input DivBear = yes; # "Plot Bearish"
input DivHiddenBear = no; # "Plot Hidden Bearish"
def na = Double.NaN;
#calc_zlema(src, length) =>
script calc_zlema {
input src = close;
input length = 10;
def ema1 = ExpAverage(src, length);
def ema2 = ExpAverage(ema1, length);
def d = ema1 - ema2;
def calc_zlema = ema1 + d;
plot return = calc_zlema;
}
#ma(s,l,bt) =>
script ma {
input s = close;
input l = 10;
input bt = no;
def ma = if bt == no then ExpAverage(s, l) else calc_zlema(s, l);
plot return = ma;
}
def v2 = (high + low + close * 2) / 4;
def v3 = ma(v2, length, UseZLEMA);
def v4 = StDev(v2, length);
def v5 = (v2 - v3) * 100 / If(v4 == 0, 1, v4);
def v6 = ma(v5, Smoothing, UseZLEMA);
def v7 = if DoubleSmooth then ma(v6, Smoothing, UseZLEMA) else v6;
def ww = (ma(v7, length, UseZLEMA) + 100) / 2 - 4;
def mm = Highest(ww, Smoothing);
plot Midline = if ww != 50 and mm != 50 and ((ww > 50 and mm > 50) or (ww < 50 and mm < 50)) then 50 else na;
Midline.SetDefaultColor(Color.GRAY);
Midline.SetStyle(Curve.SHORT_DASH);
def d = if ww > 50 then Min(ww, mm) else if mm < 50 then Max(ww, mm) else na;
def dc = if d > 50 then if d > d[1] then 1 else 0 else if d < d[1] then -1 else 0;
plot Histo = if ShowBB then na else d; # "Histo",
Histo.SetPaintingStrategy(PaintingStrategy.LINE);
Histo.AssignValueColor(if dc > 0 then Color.GREEN else if dc < 0 then Color.RED else Color.ORANGE);
AddCloud(Histo, 50, Color.GREEN, Color.RED);
AddCloud(if dc == 0 then Histo else na, 50, Color.ORANGE, Color.ORANGE);
plot Oscillator = ww; # "Oscillator"
Oscillator.SetDefaultColor(Color.RED);
plot Signal = mm; # "Signal"
Signal.SetDefaultColor(Color.GREEN);
AddCloud(Oscillator, Signal, Color.RED, Color.RED); # "OscillatorSignal Fill"
def bbBasis = SimpleMovingAvg(ww, bbLength);
def basis = if ShowBB then bbBasis else na;
def dev = bbMulti * StDev(ww, bbLength);
def bbUpper = bbBasis + dev;
def bbLower = bbBasis - dev;
def upper = if ShowBB then bbUpper else na;
def lower = if ShowBB then bbLower else na;
#// Uncomment the next line to show BB midline
plot p1 = if ShowBB then upper else na; # "Enclosing BB Upper"
plot p2 = if ShowBB then lower else na; # "Enclosing BB Lower"
p1.SetDefaultColor(Color.GRAY);
p2.SetDefaultColor(Color.GRAY);
AddCloud(p1, p2, Color.DARK_GRAY); # "Enclosing BB Fill"
def b_color = if (ww > bbUpper) then -1 else if (ww < bbLower) then 1 else na;
AddCloud(if bbBreaches then if b_color > 0 then Double.POSITIVE_INFINITY else na else na , Double.NEGATIVE_INFINITY, Color.DARK_GREEN);
AddCloud(if bbBreaches then if b_color < 0 then Double.POSITIVE_INFINITY else na else na , Double.NEGATIVE_INFINITY, Color.DARK_RED);
# --- Bar Color
def bc = if barColors then if d > 50 then if d > d[1] then 1 else 0 else if d < d[1] then -1 else 0 else na;
AssignPriceColor(if bc > 0 then Color.GREEN else if bc < 0 then Color.RED else Color.GRAY);
#----Div-----------
def divSrc = if ShowBB then ww else d;
def MaxLookback = 60; # "Max of Lookback Range"
def MinLookback = 5; # "Min of Lookback Range"
def h = high;
def l = low;
script FindPivots {
input dat = close; # default data or study being evaluated
input HL = 0; # default high or low pivot designation, -1 low, +1 high
input lbL = 5; # default Pivot Lookback Left
input lbR = 1; # default Pivot Lookback Right
##############
def _nan; # used for non-number returns
def _BN; # the current barnumber
def _VStop; # confirms that the lookforward period continues the pivot trend
def _V; # the Value at the actual pivot point
##############
_BN = BarNumber();
_nan = Double.NaN;
_VStop = if !IsNaN(dat) and lbR > 0 and lbL > 0 then
fold a = 1 to lbR + 1 with b=1 while b do
if HL > 0 then dat > GetValue(dat, -a) else dat < GetValue(dat, -a) else _nan;
if (HL > 0) {
_V = if _BN > lbL and dat == Highest(dat, lbL + 1) and _VStop
then dat else _nan;
} else {
_V = if _BN > lbL and dat == Lowest(dat, lbL + 1) and _VStop
then dat else _nan;
}
plot result = if !IsNaN(_V) and _VStop then _V else _nan;
}
#valuewhen (Cond, source, lbr, occurrence)
script valuewhen {
input cond = 0;
input src = close;
input lbr = 0;
input occurrence = 0;
def n = occurrence + 1;
def offset = fold j = 0 to 200 with p=1 while p < n + 1
do p + ( if p == n then j - n else if cond[j] == yes then 1 else 0 );
plot price = GetValue(src[lbr], offset - 1);
}
#_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 = findpivots(divSrc, -1, PivotLookback, PivotLookback);
def ph = findpivots(divSrc, 1, PivotLookback, PivotLookback);
def plFound = if !IsNaN(pl) then 1 else 0;
def phFound = if !IsNaN(ph) then 1 else 0;
def vlFound = valuewhen(plFound, divSrc, 0, 1);
def vhFound = valuewhen(phFound, divSrc, 0, 1);
def plPrice = valuewhen(plFound, l, 0, 1);
def phPrice = valuewhen(phFound, h, 0, 1);
#// Regular Bullish
def oscHL = divSrc > vlFound and _inRange(plFound[1], MaxLookback, MinLookback);
def priceLL = l < plPrice;
def bullCond = DivBull and plFound and oscHL and priceLL;
#// Hidden Bullish
def oscLL = divSrc[PivotLookback] < vlFound and _inRange(plFound[1], MaxLookback, MinLookback);
def priceHL = l[PivotLookback] > plPrice;
def hiddenBullCond = DivHiddenBull and plFound and oscLL and priceHL;
#// Regular Bearish
def oscLH = divSrc < vhFound and _inRange(phFound[1], MaxLookback, MinLookback);
def priceHH = h > phPrice;
def bearCond = DivBear and phFound and oscLH and priceHH;
#// Hidden Bearish
def oscHH = divSrc > vhFound and _inRange(phFound[1], MaxLookback, MinLookback);
def priceLH = h < phPrice;
def hiddenBearCond = DivHiddenBear and phFound and oscHH and priceLH;
#------ Bubbles
AddChartBubble(bullCond, divSrc, "R", Color.GREEN, no);
AddChartBubble(bearCond, divSrc, "R", CreateColor(156, 39, 176), yes);
AddChartBubble(hiddenBullCond, divSrc, "H", Color.DARK_GREEN, no);
AddChartBubble(hiddenBearCond, divSrc, "H", Color.DARK_RED, yes);
# ----- END Code