R-squared Adaptive T3 w/ DSL [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("R-squared Adaptive T3 w/ DSL [Loxx]",
     shorttitle='RSAT3DSL [Loxx]', 
     overlay = true, 
     timeframe="", 
     timeframe_gaps = true)
     
import loxx/loxxexpandedsourcetypes/3
import loxx/loxxmas/1

greencolor = #2DD204
redcolor = #D2042D 


darkGreenColor =  #1B7E02 
darkRedColor = #93021F

SM02 = 'Slope'
SM04 = 'Levels Crosses'

variant(type, src, len) =>
    sig = 0.0
    trig = 0.0
    special = false
    if type == "Exponential Moving Average - EMA"
        [t, s, b] = loxxmas.ema(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Fast Exponential Moving Average - FEMA"
        [t, s, b] = loxxmas.fema(src, len)
        sig := s
        trig := t
        special := b
    trig
    
_t3rSqrdAdapt(float src, float period, bool original, bool trendFollow)=>
    alpha = original ? 
         2.0 / (1.0 + period) : 
         2.0 / (2.0 + (period - 1.0) / 2.0)
    
    len = 0., SumX = 0., SumX2 = 0.
    SumY = 0., SumY2 = 0., SumXY = 0.
    
    if (len != period)
        len := period, SumX := 0
        for k = 0 to period - 1 
            SumX += k + 1
        SumX2 := 0
        for k = 0 to period - 1 
            SumX2 += (k + 1) * (k + 1)
   
    for k = 0 to period - 1 
        tprice = nz(src[k])
        SumY += tprice
        SumY2 += math.pow(tprice, 2)
        SumXY += (k + 1) * tprice
        
    Q1 = SumXY - SumX * SumY / period
    Q2 = SumX2 - SumX * SumX / period
    Q3 = SumY2 - SumY * SumY / period

    hot = Q2 * Q3 != 0 ? 
             trendFollow ? 
                 math.max(1.0 - (Q1 * Q1 / (Q2 * Q3)), 0.01) : 
                 math.max((Q1 * Q1 / (Q2 * Q3)), 0.01) : 0.

    t31 = src, t32 = src, t33 = src
    t34 = src, t35 = src, t36 = src
    price = 0.
    
    t31 := nz(t31[1]) + alpha * (src - nz(t31[1]))
    t32 := nz(t32[1]) + alpha * (t31 - nz(t32[1]))

    price := (1.0 + hot) * t31 - hot * t32
    t33 := nz(t33[1]) + alpha * (price - nz(t33[1]))
    t34 := nz(t34[1]) + alpha * (t33 - nz(t34[1]))

    price := (1.0 + hot) * t33 - hot * t34
    t35 := nz(t35[1]) + alpha * (price - nz(t35[1]))
    t36 := nz(t36[1]) + alpha * (t35 - nz(t36[1]))
    out = ((1.0 + hot) * t35 - hot * t36)
    out

    
smthtype = input.string("Kaufman", "Heikin-Ashi Better Caculation Type", options = ["AMA", "T3", "Kaufman"], group = "Basic Settings")

srcin = input.string("Close", "Source", group= "Basic Settings", 
     options = 
     ["Close", "Open", "High", "Low", "Median", "Typical", "Weighted", "Average", "Average Median Body", "Trend Biased", "Trend Biased (Extreme)", 
     "HA Close", "HA Open", "HA High", "HA Low", "HA Median", "HA Typical", "HA Weighted", "HA Average", "HA Average Median Body", "HA Trend Biased", "HA Trend Biased (Extreme)",
     "HAB Close", "HAB Open", "HAB High", "HAB Low", "HAB Median", "HAB Typical", "HAB Weighted", "HAB Average", "HAB Average Median Body", "HAB Trend Biased", "HAB Trend Biased (Extreme)"])

per = input.int(14, "Period", group = "Basic Settings")
orig = input.bool(false, "Original?", group = "Basic Settings")
fllwtrnd = input.bool(true, "Trend follow?", group = "Basic Settings")

signal_length = input.int(9, "Signal Period", group = "Signal/DSL Settings")
sigmatype = input.string("Exponential Moving Average - EMA", "Signal/DSL Smoothing", options = ["Exponential Moving Average - EMA", "Fast Exponential Moving Average - FEMA"], group = "Signal/DSL Settings")

sigtype = input.string(SM04, "Signal type", options = [SM02, SM04], group = "Signal/DSL Settings")

colorbars = input.bool(true, "Color bars?", group = "UI Options")
showSigs = input.bool(true, "Show signals?", group = "UI Options")

kfl=input.float(0.666, title="* Kaufman's Adaptive MA (KAMA) Only - Fast End", group = "Moving Average Inputs")
ksl=input.float(0.0645, title="* Kaufman's Adaptive MA (KAMA) Only - Slow End", group = "Moving Average Inputs")
amafl = input.int(2, title="* Adaptive Moving Average (AMA) Only - Fast", group = "Moving Average Inputs")
amasl = input.int(30, title="* Adaptive Moving Average (AMA) Only - Slow", group = "Moving Average Inputs")

haclose = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, close)
haopen = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, open)
hahigh = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, high)
halow = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, low)
hamedian = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hl2)
hatypical = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hlc3)
haweighted = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hlcc4)
haaverage = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, ohlc4)

src = switch srcin
	"Close" => loxxexpandedsourcetypes.rclose()
	"Open" => loxxexpandedsourcetypes.ropen()
	"High" => loxxexpandedsourcetypes.rhigh()
	"Low" => loxxexpandedsourcetypes.rlow()
	"Median" => loxxexpandedsourcetypes.rmedian()
	"Typical" => loxxexpandedsourcetypes.rtypical()
	"Weighted" => loxxexpandedsourcetypes.rweighted()
	"Average" => loxxexpandedsourcetypes.raverage()
    "Average Median Body" => loxxexpandedsourcetypes.ravemedbody()
	"Trend Biased" => loxxexpandedsourcetypes.rtrendb()
	"Trend Biased (Extreme)" => loxxexpandedsourcetypes.rtrendbext()
	"HA Close" => loxxexpandedsourcetypes.haclose(haclose)
	"HA Open" => loxxexpandedsourcetypes.haopen(haopen)
	"HA High" => loxxexpandedsourcetypes.hahigh(hahigh)
	"HA Low" => loxxexpandedsourcetypes.halow(halow)
	"HA Median" => loxxexpandedsourcetypes.hamedian(hamedian)
	"HA Typical" => loxxexpandedsourcetypes.hatypical(hatypical)
	"HA Weighted" => loxxexpandedsourcetypes.haweighted(haweighted)
	"HA Average" => loxxexpandedsourcetypes.haaverage(haaverage)
    "HA Average Median Body" => loxxexpandedsourcetypes.haavemedbody(haclose, haopen)
	"HA Trend Biased" => loxxexpandedsourcetypes.hatrendb(haclose, haopen, hahigh, halow)
	"HA Trend Biased (Extreme)" => loxxexpandedsourcetypes.hatrendbext(haclose, haopen, hahigh, halow)
	"HAB Close" => loxxexpandedsourcetypes.habclose(smthtype, amafl, amasl, kfl, ksl)
	"HAB Open" => loxxexpandedsourcetypes.habopen(smthtype, amafl, amasl, kfl, ksl)
	"HAB High" => loxxexpandedsourcetypes.habhigh(smthtype, amafl, amasl, kfl, ksl)
	"HAB Low" => loxxexpandedsourcetypes.hablow(smthtype, amafl, amasl, kfl, ksl)
	"HAB Median" => loxxexpandedsourcetypes.habmedian(smthtype, amafl, amasl, kfl, ksl)
	"HAB Typical" => loxxexpandedsourcetypes.habtypical(smthtype, amafl, amasl, kfl, ksl)
	"HAB Weighted" => loxxexpandedsourcetypes.habweighted(smthtype, amafl, amasl, kfl, ksl)
	"HAB Average" => loxxexpandedsourcetypes.habaverage(smthtype, amafl, amasl, kfl, ksl)
    "HAB Average Median Body" => loxxexpandedsourcetypes.habavemedbody(smthtype, amafl, amasl, kfl, ksl)
	"HAB Trend Biased" => loxxexpandedsourcetypes.habtrendb(smthtype, amafl, amasl, kfl, ksl)
	"HAB Trend Biased (Extreme)" => loxxexpandedsourcetypes.habtrendbext(smthtype, amafl, amasl, kfl, ksl)
	=> haclose
	
out = _t3rSqrdAdapt(src, per, orig, fllwtrnd)
sig = nz(out[1])


levelu = 0., leveld = 0., mid = 0.
levelu := (out > sig) ? variant(sigmatype, out, signal_length) : nz(levelu[1])
leveld := (out < sig) ? variant(sigmatype, out, signal_length) : nz(leveld[1])

state = 0.
if sigtype == SM02
    if (out < sig) 
        state :=-1
    if (out > sig) 
        state := 1
else if sigtype == SM04
    if (out < leveld) 
        state :=-1
    if (out > levelu)
        state := 1
        
colorout = state == -1 ? redcolor : state == 1 ? greencolor : color.gray

plot(out, "R-Squared Adaptive T3 ", color = colorout, linewidth = 3)

plot(levelu, "Level Up", color =  darkGreenColor)
plot(leveld, "Level Down", color =  darkRedColor)

barcolor(colorbars ? colorout: na)

goLong  = colorout == greencolor and colorout[1] != greencolor
goShort = colorout == redcolor and colorout[1] != redcolor

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

alertcondition(goLong, title="Long", message="R-squared Adaptive T3 w/ DSL [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="R-squared Adaptive T3 w/ DSL [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")




