FDI-Adaptive Supertrend w/ Floating Levels [Loxx]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © loxx

//@version=5
indicator("FDI-Adaptive Supertrend w/ Floating Levels [Loxx]", 
     overlay = true, 
     shorttitle="FDIASTSL [Loxx]",
     timeframe="", 
     timeframe_gaps=true)

greencolor = #2DD204
redcolor = #D2042D 

RMA(x, t) =>
    EMA1 = x
    EMA1 := na(EMA1[1]) ? x : (x - nz(EMA1[1])) * (1/t) + nz(EMA1[1])
    EMA1

fdip(float src, int per, int speedin)=>
    float fmax = ta.highest(src, per)
    float fmin = ta.lowest(src,  per)
    float length = 0
    float diff = 0
    for i = 1 to per - 1
        diff := (nz(src[i]) - fmin) / (fmax - fmin)
        if i > 0
            length += math.sqrt( math.pow(nz(diff[i]) - nz(diff[i + 1]), 2) + (1 / math.pow(per, 2)))
    float fdi = 1 + (math.log(length) + math.log(2)) / math.log(2 * per)
    float traildim = 1 / (2 - fdi)
    float alpha = traildim / 2
    int speed = math.round(speedin * alpha)
    speed
    
pine_supertrend(float src, float factor, int atrPeriod) =>
	float atr = RMA(ta.tr(true), atrPeriod)
	float upperBand = src + factor * atr
	float lowerBand = src - factor * atr
	float prevLowerBand = nz(lowerBand[1])
	float prevUpperBand = nz(upperBand[1])

	lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
	upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
	int direction = na
	float superTrend = na
	float prevSuperTrend = superTrend[1]
	if na(atr[1])
		direction := 1
	else if prevSuperTrend == prevUpperBand
		direction := close > upperBand ? -1 : 1
	else
		direction := close < lowerBand ? 1 : -1
	superTrend := direction == -1 ? lowerBand : upperBand
	[superTrend, direction]

src = input.source(hl2, "Source", group = "Basic Settings")
per = input.int(30, "Fractal Period Ingest", group = "Basic Settings")
speed = input.int(20, "Speed", group = "Basic Settings")

mult = input.float(3.0, "Multiplier", group = "Basic Settings")
adapt = input.bool(true, "Make it adaptive?", group = "Basic Settings")

flLookBack = input.int(25, "Floating Level Lookback Period", group = "Advanced Settings")
flLevelUp  = input.float(80, "Floating Levels Up Level %", group = "Advanced Settings")  
flLevelDown =  input.float(20, "Floating Levels Down Level %", group = "Advanced Settings")  

colorbars = input.bool(true, "Color bars?", group = "UI Options")
showfloat = input.bool(true, "Show Floating Levels?", group = "UI Options")
showfill = input.bool(true, "Fill Floating Levels?", group = "UI Options")
showsignals = input.bool(true, "Show signals?", group = "UI Options")

masterdom = fdip(src, per, speed)
int len = math.floor(masterdom) < 1 ? 1 : math.floor(masterdom)
len := nz(len, 1)

[supertrend, direction] = pine_supertrend(src, mult, adapt ? len : per)

mini = ta.lowest(supertrend, flLookBack)
maxi = ta.highest(supertrend, flLookBack)

rrange = maxi-mini
flu = mini+flLevelUp*rrange/100.0
fld = mini+flLevelDown*rrange/100.0
flm = mini+0.5*rrange

top = plot(showfloat ? flu : na, "Top float", color = color.new(greencolor, 50), linewidth = 1)
bot = plot(showfloat ? fld : na, "bottom float", color = color.new(redcolor, 50), linewidth = 1)
mid = plot(showfloat ? flm : na, "Mid Float", color = color.new(color.gray, 10), linewidth = 1)

fill(top, mid, title = "Top fill color", color = showfill ? color.new(greencolor, 95) : na)
fill(bot, mid,title = "Bottom fill color",  color = showfill ?  color.new(redcolor, 95) : na)

barcolor(colorbars ? direction == -1 ? greencolor : redcolor : na)
plot(supertrend, "Supertrend", color = direction == -1 ? greencolor : redcolor, linewidth = 3)

goLong = direction == -1 and direction[1] == 1 
goShort = direction == 1 and direction[1] == -1 

plotshape(goLong and showsignals, title = "Long", color = color.yellow, textcolor = color.yellow, text = "L", style = shape.triangleup, location = location.belowbar, size = size.tiny)
plotshape(goShort and showsignals, title = "Short", color = color.fuchsia, textcolor = color.fuchsia, text = "S", style = shape.triangledown, location = location.abovebar, size = size.tiny)

alertcondition(goLong, title="Long", message="FDI-Adaptive Supertrend w/ Floating Levels [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="FDI-Adaptive Supertrend w/ Floating Levels [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")

