Genesis Matrix [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("Genesis Matrix [Loxx]", 
     shorttitle="GM [Loxx]", 
     overlay = false, 
     timeframe="", 
     timeframe_gaps = true)
     
import loxx/loxxmas/1
import loxx/loxxjuriktools/1

greencolor = #2DD204
redcolor = #D2042D
    
_iT3(src, per, hot, org)=>
    a = hot
    _c1 = -a * a * a
    _c2 = 3 * a * a + 3 * a * a * a
    _c3 = -6 * a * a - 3 * a - 3 * a * a * a
    _c4 = 1 + 3 * a + a * a * a + 3 * a * a
    
    alpha = 0.
    if (org)
        alpha := 2.0 / (1.0 + per)
    else
        alpha := 2.0 / (2.0 + (per - 1.0) / 2.0)

    _t30 = src, _t31 = src
    _t32 = src, _t33 = src
    _t34 = src, _t35 = src
    
    _t30 := nz(_t30[1]) + alpha * (src -  nz(_t30[1]))
    _t31 := nz(_t31[1]) + alpha * (_t30 - nz(_t31[1]))
    _t32 := nz(_t32[1]) + alpha * (_t31 - nz(_t32[1]))
    _t33 := nz(_t33[1]) + alpha * (_t32 - nz(_t33[1]))
    _t34 := nz(_t34[1]) + alpha * (_t33 - nz(_t34[1]))
    _t35 := nz(_t35[1]) + alpha * (_t34 - nz(_t35[1]))
    
    out =
         _c1 * _t35 + _c2 * _t34 +
         _c3 * _t33 +  _c4 * _t32
    out

_calcBaseUnit() =>
    bool isForexSymbol = syminfo.type == "forex"
    bool isYenPair = syminfo.currency == "JPY"
    float result = isForexSymbol ? isYenPair ? 0.01 : 0.0001 : syminfo.mintick
    result

ccisrc = input.source(close, "CCI Source", group = "CCI Settings")
cciper = input.int(20, "CCI Period", group = "CCI Settings")
madev = input.int(14, "MA Deviation Period", group = "CCI Settings")
madevtype = input.string("Exponential Moving Average - EMA", "Deviation MA Type", options = ["ADXvma - Average Directional Volatility Moving Average",  "Ahrens Moving Average"
     , "Alexander Moving Average - ALXMA", "Double Exponential Moving Average - DEMA", "Double Smoothed Exponential Moving Average - DSEMA"
     , "Exponential Moving Average - EMA", "Fast Exponential Moving Average - FEMA", "Fractal Adaptive Moving Average - FRAMA"
     , "Hull Moving Average - HMA", "IE/2 - Early T3 by Tim Tilson", "Integral of Linear Regression Slope - ILRS"
     , "Instantaneous Trendline", "Laguerre Filter", "Leader Exponential Moving Average", "Linear Regression Value - LSMA (Least Squares Moving Average)"
     , "Linear Weighted Moving Average - LWMA", "McGinley Dynamic", "McNicholl EMA", "Non-Lag Moving Average", "Parabolic Weighted Moving Average"
     , "Recursive Moving Trendline", "Simple Moving Average - SMA", "Sine Weighted Moving Average", "Smoothed Moving Average - SMMA"
     , "Smoother", "Super Smoother", "Three-pole Ehlers Butterworth", "Three-pole Ehlers Smoother"
     , "Triangular Moving Average - TMA", "Triple Exponential Moving Average - TEMA", "Two-pole Ehlers Butterworth", "Two-pole Ehlers smoother"
     , "Volume Weighted EMA - VEMA", "Zero-Lag DEMA - Zero Lag Double Exponential Moving Average", "Zero-Lag Moving Average"
     , "Zero Lag TEMA - Zero Lag Triple Exponential Moving Average"],
     group = "CCI Settings")
     
jsmth = input.int(5, "Jurik Smoothing Period", group = "CCI Settings")
phs = input.float(0, "Jurik Phase", group = "CCI Settings")

t3src = input.source(close, "T3 Source", group = "T3 Settings")
t3per = input.int(8, "T3 Period", group = "T3 Settings")
t3hot = input.float(1, "T3 Factor", minval = 0, maxval = 1, step = 0.01, group = "T3 Settings")
tempswtch = input.bool(false, "T3 Original", group = "T3 Settings")

ssltype = input.string("Exponential Moving Average - EMA", "Deviation MA Type", options = ["ADXvma - Average Directional Volatility Moving Average",  "Ahrens Moving Average"
     , "Alexander Moving Average - ALXMA", "Double Exponential Moving Average - DEMA", "Double Smoothed Exponential Moving Average - DSEMA"
     , "Exponential Moving Average - EMA", "Fast Exponential Moving Average - FEMA", "Fractal Adaptive Moving Average - FRAMA"
     , "Hull Moving Average - HMA", "IE/2 - Early T3 by Tim Tilson", "Integral of Linear Regression Slope - ILRS"
     , "Instantaneous Trendline", "Laguerre Filter", "Leader Exponential Moving Average", "Linear Regression Value - LSMA (Least Squares Moving Average)"
     , "Linear Weighted Moving Average - LWMA", "McGinley Dynamic", "McNicholl EMA", "Non-Lag Moving Average", "Parabolic Weighted Moving Average"
     , "Recursive Moving Trendline", "Simple Moving Average - SMA", "Sine Weighted Moving Average", "Smoothed Moving Average - SMMA"
     , "Smoother", "Super Smoother", "Three-pole Ehlers Butterworth", "Three-pole Ehlers Smoother"
     , "Triangular Moving Average - TMA", "Triple Exponential Moving Average - TEMA", "Two-pole Ehlers Butterworth", "Two-pole Ehlers smoother"
     , "Volume Weighted EMA - VEMA", "Zero-Lag DEMA - Zero Lag Double Exponential Moving Average", "Zero-Lag Moving Average"
     , "Zero Lag TEMA - Zero Lag Triple Exponential Moving Average"],
     group = "SSL Settings")
sslper = input.int(20, "SSL Period", group = "SSL Settings")
clsper = input.int(1, "Close Period", group = "SSL Settings", minval =0)

tvitype = input.string("Exponential Moving Average - EMA", "Deviation MA Type", options = ["ADXvma - Average Directional Volatility Moving Average",  "Ahrens Moving Average"
     , "Alexander Moving Average - ALXMA", "Double Exponential Moving Average - DEMA", "Double Smoothed Exponential Moving Average - DSEMA"
     , "Exponential Moving Average - EMA", "Fast Exponential Moving Average - FEMA", "Fractal Adaptive Moving Average - FRAMA"
     , "Hull Moving Average - HMA", "IE/2 - Early T3 by Tim Tilson", "Integral of Linear Regression Slope - ILRS"
     , "Instantaneous Trendline", "Laguerre Filter", "Leader Exponential Moving Average", "Linear Regression Value - LSMA (Least Squares Moving Average)"
     , "Linear Weighted Moving Average - LWMA", "McGinley Dynamic", "McNicholl EMA", "Non-Lag Moving Average", "Parabolic Weighted Moving Average"
     , "Recursive Moving Trendline", "Simple Moving Average - SMA", "Sine Weighted Moving Average", "Smoothed Moving Average - SMMA"
     , "Smoother", "Super Smoother", "Three-pole Ehlers Butterworth", "Three-pole Ehlers Smoother"
     , "Triangular Moving Average - TMA", "Triple Exponential Moving Average - TEMA", "Two-pole Ehlers Butterworth", "Two-pole Ehlers smoother"
     , "Volume Weighted EMA - VEMA", "Zero-Lag DEMA - Zero Lag Double Exponential Moving Average", "Zero-Lag Moving Average"
     , "Zero Lag TEMA - Zero Lag Triple Exponential Moving Average"],
     group = "TVI Settings")
tviema = input.int(12, "TVI EMA Period", group = "TVI Settings")
tviavg = input.int(12, "TVI Average Period", group = "TVI Settings")
tvismth = input.int(5, "TVI Smoothing Period", group = "TVI Settings")

colorbars = input.bool(false, "Color bars?", group = "UI Options")

frama_FC = input.int(defval=1, title="* Fractal Adjusted (FRAMA) Only - FC", group = "Moving Average Inputs")
frama_SC = input.int(defval=200, title="* Fractal Adjusted (FRAMA) Only - SC", group = "Moving Average Inputs")
instantaneous_alpha = input.float(defval=0.07, minval = 0, title="* Instantaneous Trendline (INSTANT) Only - Alpha", group = "Moving Average Inputs")
_laguerre_alpha = input.float(title='* Laguerre Filter (LF) Only - Alpha', minval=0, maxval=1, step=0.1, defval=0.7, group = "Moving Average Inputs")
lsma_offset = input.int(defval=0, title="* Least Squares Moving Average (LSMA) Only - Offset", group = "Moving Average Inputs")
_pwma_pwr = input.int(2, '* Parabolic Weighted Moving Average (PWMA) Only - Power', minval=0, group = "Moving Average Inputs")
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")

variant(type, src, len) =>
    sig = 0.0
    trig = 0.0
    special = false
    if type == "ADXvma - Average Directional Volatility Moving Average"
        [t, s, b] = loxxmas.adxvma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Ahrens Moving Average"
        [t, s, b] = loxxmas.ahrma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Alexander Moving Average - ALXMA"
        [t, s, b] = loxxmas.alxma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Double Exponential Moving Average - DEMA"
        [t, s, b] = loxxmas.dema(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Double Smoothed Exponential Moving Average - DSEMA"
        [t, s, b] = loxxmas.dsema(src, len)
        sig := s
        trig := t
        special := b
    else 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
    else if type == "Fractal Adaptive Moving Average - FRAMA"
        [t, s, b] = loxxmas.frama(src, len, frama_FC, frama_SC)
        sig := s
        trig := t
        special := b
    else if type == "Hull Moving Average - HMA"
        [t, s, b] = loxxmas.hma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "IE/2 - Early T3 by Tim Tilson"
        [t, s, b] = loxxmas.ie2(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Integral of Linear Regression Slope - ILRS"
        [t, s, b] = loxxmas.ilrs(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Instantaneous Trendline"
        [t, s, b] = loxxmas.instant(src, instantaneous_alpha)
        sig := s
        trig := t
        special := b
    else if type == "Laguerre Filter"
        [t, s, b] = loxxmas.laguerre(src, _laguerre_alpha)
        sig := s
        trig := t
        special := b
    else if type == "Leader Exponential Moving Average"
        [t, s, b] = loxxmas.leader(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Linear Regression Value - LSMA (Least Squares Moving Average)"
        [t, s, b] = loxxmas.lsma(src, len, lsma_offset)
        sig := s
        trig := t
        special := b
    else if type == "Linear Weighted Moving Average - LWMA"
        [t, s, b] = loxxmas.lwma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "McGinley Dynamic"
        [t, s, b] = loxxmas.mcginley(src, len)
        sig := s
        trig := t
        special := b
    else if type == "McNicholl EMA"
        [t, s, b] = loxxmas.mcNicholl(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Non-Lag Moving Average"
        [t, s, b] = loxxmas.nonlagma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Parabolic Weighted Moving Average"
        [t, s, b] = loxxmas.pwma(src, len, _pwma_pwr)
        sig := s
        trig := t
        special := b
    else if type == "Recursive Moving Trendline"
        [t, s, b] = loxxmas.rmta(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Simple Moving Average - SMA"
        [t, s, b] = loxxmas.sma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Sine Weighted Moving Average"
        [t, s, b] = loxxmas.swma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Smoothed Moving Average - SMMA"
        [t, s, b] = loxxmas.smma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Smoother"
        [t, s, b] = loxxmas.smoother(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Super Smoother"
        [t, s, b] = loxxmas.super(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Three-pole Ehlers Butterworth"
        [t, s, b] = loxxmas.threepolebuttfilt(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Three-pole Ehlers Smoother"
        [t, s, b] = loxxmas.threepolesss(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Triangular Moving Average - TMA"
        [t, s, b] = loxxmas.tma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Triple Exponential Moving Average - TEMA"
        [t, s, b] = loxxmas.tema(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Two-pole Ehlers Butterworth"
        [t, s, b] = loxxmas.twopolebutter(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Two-pole Ehlers smoother"
        [t, s, b] = loxxmas.twopoless(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Volume Weighted EMA - VEMA"
        [t, s, b] = loxxmas.vwema(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Zero-Lag DEMA - Zero Lag Double Exponential Moving Average"
        [t, s, b] = loxxmas.zlagdema(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Zero-Lag Moving Average"
        [t, s, b] = loxxmas.zlagma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Zero Lag TEMA - Zero Lag Triple Exponential Moving Average"
        [t, s, b] = loxxmas.zlagtema(src, len)
        sig := s
        trig := t
        special := b
    trig

_emaDev(type, price, period)=>
    alpha = 2.0/(1.0+period)
    wEMAdev0 = price, wEMAdev1 = price
    wEMAdev0 := variant(type, price, period)
    wEMAdev1 := variant(type, price*price, period)
    out = math.sqrt(period*(wEMAdev1 - wEMAdev0 * wEMAdev0) / math.max(period-1, 1))
    out

_cci(type, src, len, malen, smth, phase)=>
    price = loxxjuriktools.jurik_filt(src, smth, phase)
    avg = loxxjuriktools.jurik_filt(price, len, phase)
    dev = math.max(_emaDev(type, price, malen), -2e10)
    val = (dev!=0) ? (price - avg) / (0.015 * dev) : 0.
    val

_tvi(type, tr, s, u)=>
    upTic = (volume + (close - open) / _calcBaseUnit()) / 2
    dnTic = volume - upTic
    ema2 = variant(type, upTic, s)
    ema4 = variant(type, dnTic, s)
    avgUp = variant(type, ema2, tr)
    avgDn = variant(type, ema4, tr)
    ema5 = variant(type, 100.0 * (avgUp-avgDn) / (avgUp+avgDn), u) 
    val = (avgUp+avgDn != 0) ? ema5 : 0 
    val
    
_ssl(type, len, clper)=>
    varHigh = variant(type, high, len)
    varLow = variant(type, low, len)
    varClose = variant(type, close, clper)
    Hlv = 0.
    Hlv := varClose > varHigh ? 1 : varClose < varLow ? -1 : Hlv[1]
    sslDown = Hlv < 0 ? varHigh : varLow
    sslUp = Hlv < 0 ? varLow : varHigh
    [sslUp, sslDown]
    
tvi = _tvi(tvitype, tviavg, tviema, tvismth)
[sslUp, sslDown] = _ssl(ssltype, sslper, clsper)
t3out = _iT3(t3src, t3per, t3hot, tempswtch) 
cci = _cci(madevtype, ccisrc, cciper, madev, jsmth, phs)


plotshape(1, color = t3out > nz(t3out[1])  ? greencolor : redcolor, style = shape.square, location = location.absolute)
plotshape(2, color = sslUp > sslDown ? greencolor : redcolor, style = shape.square, location = location.absolute)
plotshape(3, color = cci > 0 ? greencolor : redcolor, style = shape.square, location = location.absolute)
plotshape(4, color =  tvi > 0 ? greencolor : redcolor, style = shape.square, location = location.absolute)

colorout = 
     tvi > 0 and sslUp > sslDown and t3out > nz(t3out[1]) and cci > 0 ? greencolor : 
     tvi < 0 and sslUp < sslDown and t3out < nz(t3out[1]) and cci < 0 ? redcolor : 
     color.gray

barcolor(colorbars ? colorout : na)

goLong_pre = tvi > 0 and sslUp > sslDown and t3out > nz(t3out[1]) and cci > 0 
goShort_pre = tvi < 0 and sslUp < sslDown and t3out < nz(t3out[1]) and cci < 0 

contSwitch = 0
contSwitch := nz(contSwitch[1])
contSwitch := goLong_pre ? 1 : goShort_pre ? -1 : contSwitch

goLong = goLong_pre and ta.change(contSwitch)
goShort = goShort_pre and ta.change(contSwitch)

plotshape(colorout == redcolor ? 5 : na, style = shape.triangledown, location = location.absolute, size = size.auto, color = color.fuchsia)
plotshape(colorout == greencolor ? 0 : na, style = shape.triangleup, location = location.absolute, size = size.auto, color = color.yellow)

alertcondition(goLong, title="Long", message="Genesis Matrix [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="Genesis Matrix [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")

























