SAT_LIB
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © sosso_bott

//@version=5
// @description TODO: This library regroups indicator's functions i use a lot
library("SAT_LIB")
no_rep(_symbol, _res, _src) =>
    request.security(_symbol, _res, _src[barstate.isrealtime ? 1:0])[barstate.isrealtime ? 0 : 1]
// ######################################## RENKO LEVELS ######################################
// @function TODO: RenkoLevels indicator by Mongolor function
// @param upColor1 TODO: (Type: color) renko up color
// @param dnColor1 TODO: (Type: color) renko down color
// @param HIGH TODO: (Type: float) 
// @param LOW TODO:  (Type: float) 
// @param ATR TODO: (Type: float)
// @returns TODO: Renkolevelsfloat 
export getRENKOLEVELS(color upColor1, color dnColor1, float HIGH, float LOW, float ATR) =>   

    float RENKOUP   = na
    float RENKODN   = na
    COLOR           = color.white
    float H         = na
    float BUY       = na
    float SELL      = na
    bool CHANGE     = na
    
    RENKOUP         := na(RENKOUP[1]) ? ((HIGH+LOW)/2)+(ATR/2) : RENKOUP[1]
    RENKODN         := na(RENKOUP[1]) ? ((HIGH+LOW)/2)-(ATR/2) : RENKODN[1]
    H               := na(RENKOUP[1]) or na(RENKODN[1]) ? RENKOUP-RENKODN : RENKOUP[1]-RENKODN[1]
    COLOR           := na(COLOR[1]) ? color.white : COLOR[1]
    BUY             := na(BUY[1]) ? 0 : BUY[1]
    SELL            := na(SELL[1]) ? 0 : SELL[1]
    CHANGE          := false
    renkoState      =  0
    
    if(not CHANGE and close >= RENKOUP[1]+H*3)
        CHANGE      := true
        RENKOUP     := RENKOUP[1]+ATR*3
        RENKODN     := RENKOUP[1]+ATR*2
        COLOR       := upColor1
        SELL        := 0
        BUY         := BUY+3
    
    if(not CHANGE and close >= RENKOUP[1]+H*2)
        CHANGE      := true
        RENKOUP     := RENKOUP[1]+ATR*2
        RENKODN     := RENKOUP[1]+ATR
        COLOR       :=  upColor1
        SELL        := 0
        BUY         := BUY+2
    
    if(not CHANGE and close >= RENKOUP[1]+H)
        CHANGE      := true
        RENKOUP     := RENKOUP[1]+ATR
        RENKODN     := RENKOUP[1]
        COLOR       :=  upColor1
        SELL        := 0
        BUY         := BUY+1
    ///////////////  sell \\\\\\\\\\\\\\\\\\\\\
    if(not CHANGE and close <= RENKODN[1]-H*3)
        CHANGE      := true
        RENKODN     := RENKODN[1]-ATR*3
        RENKOUP     := RENKODN[1]-ATR*2
        COLOR       := dnColor1
        BUY         := 0
        SELL        := SELL+3
    
    if(not CHANGE and close <= RENKODN[1]-H*2)
        CHANGE      := true
        RENKODN     := RENKODN[1]-ATR*2
        RENKOUP     := RENKODN[1]-ATR
        COLOR       := dnColor1
        BUY         := 0
        SELL        := SELL+2
    
    if(not CHANGE and close <= RENKODN[1]-H)
        CHANGE      := true
        RENKODN     := RENKODN[1]-ATR
        RENKOUP     := RENKODN[1]
        COLOR       := dnColor1
        BUY         := 0
        SELL        := SELL+1
        
    brenko          = BUY > 0 
    srenko          = SELL > 0
    diff            = (RENKOUP - RENKODN) / RENKODN *100
    RENKOMID        = RENKODN*(1+(diff/200))
    EXTRAUP         = RENKOUP * (1 + ((RENKOUP - RENKOMID)/RENKOUP))
    EXTRADN         = RENKODN * (1 - ((RENKOMID - RENKODN)/RENKOMID))
    [brenko, srenko, diff, RENKOMID, EXTRAUP, EXTRADN, RENKOUP, RENKODN, COLOR, CHANGE]
// ####################################### RENKO LEVELS END ###################################


// ######################################## RENKO RSI #########################################
// @function TODO: RENKO RSI indicator by @LonesomeTheBlue function
// @param valu TODO: (Type: float) 
// @returns TODO: ATR boxSize
export conv_atr(float valu)=>
    a = 0
    num = syminfo.mintick
    s = valu
    if na(s)
        s := syminfo.mintick
    if num < 1
        for i = 1 to 20
            num := num * 10
            if num > 1
                break
            a := a +1
    for x = 1 to a 
        s := s * 10
    s := math.round(s)
    for x = 1 to a
        s := s / 10
    s := s < syminfo.mintick  ? syminfo.mintick : s
    s

// @function TODO: RENKO RSI indicator by @LonesomeTheBlue function
// @param mode TODO: (Type: string) 
// @param atrboxsize TODO: (Type: float) 
// @param boxsize TODO: (Type: float) 
// @param source TODO: (Type: string) 
// @returns TODO: [box, icloseprice, iopenprice, trend]
export boxTreatment(string mode, float atrboxsize, float boxsize, string source) =>
    float box           = na
    box                 := na(box[1]) ? mode == 'ATR' ? atrboxsize : boxsize : box[1] 
    
    reversal            = 2
    top                 = 0.0
    bottom              = 0.0
    trend               = 0
    trend               := barstate.isfirst ? 0 : nz(trend[1])
    currentprice        = 0.0
    currentprice        := source == 'close' ? close : trend == 1 ? high : low
    float beginprice    = na
    beginprice          := barstate.isfirst ? math.floor(open / box) * box : nz(beginprice[1])
    iopenprice          = 0.0
    icloseprice         = 0.0
    
    if trend == 0 and box * reversal <= math.abs(beginprice - currentprice)
        if beginprice > currentprice
            numcell = math.floor(math.abs(beginprice - currentprice) / box)
            iopenprice := beginprice
            icloseprice := beginprice - numcell * box
            trend := -1
        if beginprice < currentprice
            numcell = math.floor(math.abs(beginprice - currentprice) / box)
            iopenprice := beginprice
            icloseprice := beginprice + numcell * box
            trend := 1
    
    if trend == -1
        nok = true
        if beginprice > currentprice and box <= math.abs(beginprice - currentprice)
            numcell = math.floor(math.abs(beginprice - currentprice) / box)
            icloseprice := beginprice - numcell * box
            trend := -1
            beginprice := icloseprice
            nok := false
        else
            iopenprice := iopenprice == 0 ? nz(iopenprice[1]) : iopenprice
            icloseprice := icloseprice == 0 ? nz(icloseprice[1]) : icloseprice
        
        tempcurrentprice = source == 'close' ? close : high
        if beginprice < tempcurrentprice and box * reversal <= math.abs(beginprice - tempcurrentprice) and nok //new column
            numcell = math.floor(math.abs(beginprice - tempcurrentprice) / box)
            iopenprice := beginprice + box
            icloseprice := beginprice + numcell * box
            trend := 1
            beginprice := icloseprice
        else
            iopenprice := iopenprice == 0 ? nz(iopenprice[1]) : iopenprice
            icloseprice := icloseprice == 0 ? nz(icloseprice[1]) : icloseprice
    else        
        if trend == 1
            nok = true
            if beginprice < currentprice and box <= math.abs(beginprice - currentprice)
                numcell = math.floor(math.abs(beginprice - currentprice) / box)
                icloseprice := beginprice + numcell * box
                trend := 1
                beginprice := icloseprice
                nok := false
            else
                iopenprice := iopenprice == 0 ? nz(iopenprice[1]) : iopenprice
                icloseprice := icloseprice == 0 ? nz(icloseprice[1]) : icloseprice
        
            tempcurrentprice = source == 'close' ? close : low
            if beginprice > tempcurrentprice and box * reversal <= math.abs(beginprice - tempcurrentprice) and nok //new column
                numcell = math.floor(math.abs(beginprice - tempcurrentprice) / box)
                iopenprice := beginprice - box
                icloseprice := beginprice - numcell * box
                trend := -1
                beginprice := icloseprice
            else
                iopenprice := iopenprice == 0 ? nz(iopenprice[1]) : iopenprice
                icloseprice := icloseprice == 0 ? nz(icloseprice[1]) : icloseprice    
    
    //if icloseprice changed then recalculate box size
    box         := ta.change(icloseprice) ?  mode == 'ATR' ? atrboxsize :  boxsize : box
    [box, icloseprice, iopenprice, trend]

// @function TODO: RENKO RSI indicator by @LonesomeTheBlue function
// @param ser TODO: (Type: float) 
// @param len TODO: (Type: int) 
// @param trcnt TODO: (Type: int) 
// @param obox TODO: (Type: float) 
// @param trch TODO: (Type: bool) 
// @param trend TODO: (Type: int) 
// @returns TODO: renkRSI
export Renko_rsi(float ser, int len, int trcnt, float obox, bool trch, int trend)=>
    float res = na 
    if nz(ser) != 0 and nz(ser[trcnt]) != 0
        float rsup = na
        float rsdn = na
        if ta.change(ser) == 0
            res := res[1]
            rsup := rsup[1]
            rsdn := rsdn[1]
        if ta.change(ser) != 0
            if math.abs(ser - ser[trcnt]) == obox
                u = math.max(ser - ser[trcnt], 0)    // upward change
                d = math.max(ser[trcnt] - ser, 0)    // downward change
                rsup := (u + (len - 1) * nz(rsup[trcnt])) / len
                rsdn := (d + (len - 1) * nz(rsdn[trcnt])) / len
                rs = rsup / rsdn
                res := rsdn == 0 ? 100 : 100 - 100 / (1 + rs)
            if math.abs(ser - ser[trcnt]) > obox
                bb = ser > ser[trcnt] ? obox : -obox
                u = trch ? math.max(bb*2, 0) : math.max(bb, 0)    // upward change
                d = trch ? math.max(-bb*2, 0) : math.max(-bb, 0)    // downward change
                rsup := (u + (len - 1) * nz(rsup[trcnt])) / len
                rsdn := (d + (len - 1) * nz(rsdn[trcnt])) / len
                ktsy = trch ? 3 : 2
                cc = ser > nz(ser[trcnt]) ? nz(ser[trcnt]) + ktsy * obox : nz(ser[trcnt]) - ktsy * obox
                k = math.floor((math.abs(cc - ser) / obox))
                k := k > 20 ? 20 : k
                loop = trch ? (trend == -1 and cc>=ser) or (trend == 1 and cc<=ser) ? true : false : true
                if loop
                    for x = 0 to k
                        u = math.max(bb, 0)    // upward change
                        d = math.max(-bb, 0)    // downward change
                        rsup := (u + (len - 1) * rsup) / len
                        rsdn := (d + (len - 1) * rsdn) / len
                
                rs = rsup / rsdn
                res := rsdn == 0 ? 100 : 100 - 100 / (1 + rs)
    res
// ##################################### RENKO RSI END #########################################
  

// ############################# DOUBLE MOVING AVERAGES ########################################
//alligator
smma(src, length) =>
	smma    =  0.0
	smma    := na(smma[1]) ? ta.sma(src, length) : (smma[1] * (length - 1) + src) / length
	smma
	
// @function TODO: [ SMA , SMMA , EMA , VWMA , HULL, TEMA ] Between this options this function return a fast and a slow moving averages.
// @param fast_ma_type TODO: string fast MA type
// @param fast_ma_length TODO: int fast MA type
// @param fast_ma_src TODO: float fast MA source
// @param fast_ma_type TODO: string slow MA type
// @param fast_ma_length TODO: int slow MA type
// @param fast_ma_src TODO: float slow MA source
// @returns TODO: [fast_ma, slow_ma]
export getDoubleMovingAverages(string fast_ma_type, simple int fast_ma_length, float fast_ma_src, string slow_ma_type, simple int slow_ma_length, float slow_ma_src) =>
    //FAST MOVING AVERAGES
    e1          = ta.ema(fast_ma_src, fast_ma_length)									
    fast_sma    = ta.sma(fast_ma_src, fast_ma_length) 												
    fsm_ma      = smma(fast_ma_src, fast_ma_length)											
    fvolume_ma  = ta.vwma(fast_ma_src, fast_ma_length)	
    hullma      = ta.wma(2 * ta.wma(fast_ma_src, fast_ma_length/2) - ta.wma(fast_ma_src, fast_ma_length), math.floor(math.sqrt(fast_ma_length))) 
    
    ema1        = ta.ema(fast_ma_src, fast_ma_length)
    ema2        = ta.ema(ema1, fast_ma_length)
    ema3        = ta.ema(ema2, fast_ma_length)
    tema        = 3 * (ema1 - ema2) + ema3													
    
    //SLOW MOVING AVERAGES
    e           = ta.ema(slow_ma_src, slow_ma_length)	
    slow_sma    = ta.sma(slow_ma_src, slow_ma_length)
    sm_ma       = smma(slow_ma_src, slow_ma_length)
    volume_ma   = ta.vwma(slow_ma_src, slow_ma_length)
    hullma1     = ta.wma(2 * ta.wma(slow_ma_src, slow_ma_length/2) - ta.wma(slow_ma_src, slow_ma_length), math.floor(math.sqrt(slow_ma_length)))

    ema4        = ta.ema(slow_ma_src, slow_ma_length)
    ema5        = ta.ema(ema4, slow_ma_length)
    ema6        = ta.ema(ema5, slow_ma_length)
    tema1       = 3 * (ema4 - ema5) + ema6	
    
    choice_fast = fast_ma_type  == "TEMA" ? tema : fast_ma_type  == "SMA" ? fast_sma : fast_ma_type == "HULL" ? hullma  : fast_ma_type == "SMMA" ? fsm_ma :  fast_ma_type =="EMA" ? e1:fast_ma_type  =="VWMA"? fvolume_ma:na
    choice_slow = slow_ma_type   == "TEMA" ? tema1: slow_ma_type   == "SMA" ? slow_sma : fast_ma_type == "HULL" ? hullma1 : slow_ma_type   == "SMMA" ? sm_ma :  slow_ma_type   =="EMA"? e :slow_ma_type   =="VWMA"? volume_ma :na
    
    b_maz       = choice_fast[1] < choice_slow[1] and choice_fast > choice_slow  //crossover(choice_fast, choice_slow)
    s_maz       = choice_fast[1] > choice_slow[1] and choice_fast < choice_slow //crossunder(choice_fast, choice_slow)

    var int maz_state   =  0

    if b_maz
        maz_state   := 1

    if s_maz
        maz_state   := -1
    
    [choice_fast, choice_slow, b_maz, s_maz, maz_state]


// @function TODO: [ SMA , SMMA , EMA , VWMA , HULL, TEMA ] Between this options this function return a fast and a slow moving averages.
// @param fast_ma_type TODO: string fast MA type
// @param fast_ma_length TODO: int fast MA type
// @param fast_ma_src TODO: float fast MA source
// @returns TODO: fast_ma
export getMovingAverage(string fast_ma_type, simple int fast_ma_length, float fast_ma_src) =>
    e1          = ta.ema(fast_ma_src, fast_ma_length)									
    fast_sma    = ta.sma(fast_ma_src, fast_ma_length) 												
    fsm_ma      = smma(fast_ma_src, fast_ma_length)											
    fvolume_ma  = ta.vwma(fast_ma_src, fast_ma_length)	
    hullma      = ta.wma(2 * ta.wma(fast_ma_src, fast_ma_length/2) - ta.wma(fast_ma_src, fast_ma_length), math.floor(math.sqrt(fast_ma_length))) 
    
    ema1        = ta.ema(fast_ma_src, fast_ma_length)
    ema2        = ta.ema(ema1, fast_ma_length)
    ema3        = ta.ema(ema2, fast_ma_length)
    tema        = 3 * (ema1 - ema2) + ema3													

    choice_fast = fast_ma_type  == "TEMA" ? tema : fast_ma_type  == "SMA" ? fast_sma : fast_ma_type == "HULL" ? hullma  : fast_ma_type == "SMMA" ? fsm_ma :  fast_ma_type =="EMA" ? e1:fast_ma_type  =="VWMA"? fvolume_ma:na
    choice_fast
// ############################# DOUBLE MOVING AVERAGES END ####################################


// #############################        RANGE FILTER        #################################### By @DonovanWall
//Conditional Sampling EMA Function 
export Cond_EMA(float x, bool cond, int n)=>
    var val     = array.new_float(0)
    var ema_val = array.new_float(1)
    if cond
        array.push(val, x)
        if array.size(val) > 1
            array.remove(val, 0)
        if na(array.get(ema_val, 0))
            array.fill(ema_val, array.get(val, 0))
        array.set(ema_val, 0, (array.get(val, 0) - array.get(ema_val, 0))*(2/(n + 1)) + array.get(ema_val, 0))
    EMA = array.get(ema_val, 0)
    EMA

//Conditional Sampling SMA Function
export Cond_SMA(float x, bool cond, int n)=>
    var vals = array.new_float(0)
    if cond
        array.push(vals, x)
        if array.size(vals) > n
            array.remove(vals, 0)
    SMA = array.avg(vals)
    SMA

//Standard Deviation Function
export Stdev(float x,  int n)=>
    math.sqrt(Cond_SMA(math.pow(x, 2), 1, n) - math.pow(Cond_SMA(x, 1, n), 2))

//Range Size Function
export rng_size(float x,string scale, float qty, int n)=> 
    ATR      = Cond_EMA(ta.tr(true), 1, n)
    AC       = Cond_EMA(math.abs(x - x[1]), 1, n)
    SD       = Stdev(x, n)
    rng_size = scale=="Pips" ? qty*0.0001 : scale=="Points" ? qty*syminfo.pointvalue : scale=="% of Price" ? close*qty/100 : scale=="ATR" ? qty*ATR :
               scale=="Average Change" ? qty*AC : scale=="Standard Deviation" ? qty*SD : scale=="Ticks" ? qty*syminfo.mintick : qty   
// #############################        RANGE FILTER        ####################################


// #############################          HOTT LOTT         #################################### By @KivancOzbilgic
// @function TODO: HOTT LOTT indicator by @KivancOzbilgic function
// @param src TODO: float 
// @param length TODO: int
// @returns TODO: float VAR
export Var_Func(float src, int length)=>
    valpha=2/(length+1)
    vud1=src>src[1] ? src-src[1] : 0
    vdd1=src<src[1] ? src[1]-src : 0
    vUD=math.sum(vud1,9)
    vDD=math.sum(vdd1,9)
    vCMO=nz((vUD-vDD)/(vUD+vDD))
    VAR=0.0
    VAR:=nz(valpha*math.abs(vCMO)*src)+(1-valpha*math.abs(vCMO))*nz(VAR[1])
    VAR

// @function TODO: WWMA by @KivancOzbilgic function
// @param src TODO: float 
// @param length TODO: int
// @returns TODO: float WWMA
export Wwma_Func(float src, int length) =>
    wwalpha = 1/ length
    WWMA = 0.0
    WWMA := wwalpha*src + (1-wwalpha)*nz(WWMA[1])
    WWMA

// @function TODO: ZLEMA by @KivancOzbilgic function
// @param src TODO: float 
// @param length TODO: int
// @returns TODO: float ZLEMA
export Zlema_Func(float src, int length) =>
    zxLag = length/2==math.round(length/2) ? length/2 : (length - 1) / 2
    zxEMAData = (src + (src - src[zxLag]))
    ZLEMA = ta.ema(zxEMAData, length)
    ZLEMA

// @function TODO: TSF by @KivancOzbilgic function
// @param src TODO: float 
// @param length TODO: int
// @returns TODO: float ZLEMA
export Tsf_Func(float src, int length) =>
    lrc = ta.linreg(src, length, 0)
    lrc1 = ta.linreg(src,length,1)
    lrs = (lrc-lrc1)
    TSF = ta.linreg(src, length, 0)+lrs
    TSF

// @function TODO: getMA by @KivancOzbilgic function cutomised
// @param mav TODO: string
// @param src TODO: float 
// @param length TODO: int
// @param x TODO: string type
// @param VAR1 TODO: float
// @param VAR2 TODO: float
// @param WWMA1 TODO: float
// @param WWMA2 TODO: float
// @param ZLEMA1 TODO: float
// @param ZLEMA2 TODO: float
// @param TSF1 TODO: float
// @param TSF2 TODO: float
// @returns TODO: float ZLEMA
export getMA(string mav, float src,simple int length, string x, float VAR1, float VAR2, float WWMA1, float WWMA2, float ZLEMA1, float ZLEMA2, float TSF1, float TSF2) =>
    ma1 = 0.0
    ma2 = 0.0
    if mav == "SMA" and x == "m1"
        ma1 := ta.sma(src, length)
        ma1

    if mav == "SMA" and x == "m2"
        ma2 := ta.sma(src, length)
        ma2

    if mav == "EMA" and x == "m1"
        ma1 := ta.ema(src, length)
        ma1

    if mav == "EMA" and x == "m2"
        ma2 := ta.ema(src, length)
        ma2

    if mav == "WMA" and x == "m1"
        ma1 := ta.wma(src, length)
        ma1

    if mav == "WMA" and x == "m2"
        ma2 := ta.wma(src, length)
        ma2

    if mav == "TMA" and x == "m1"
        ma1 := ta.sma(ta.sma(src, math.ceil(length / 2)), math.floor(length / 2) + 1)
        ma1    

    if mav == "TMA" and x == "m2"
        ma2 := ta.sma(ta.sma(src, math.ceil(length / 2)), math.floor(length / 2) + 1)
        ma2

    if mav == "VAR" and x == "m1"
        ma1 := VAR1
        ma1

    if mav == "VAR" and x == "m2"
        ma2 := VAR2
        ma2

    if mav == "WWMA" and x == "m1"
        ma1 := WWMA1
        ma1

    if mav == "WWMA" and x == "m2"
        ma2 := WWMA2
        ma2

    if mav == "ZLEMA" and x == "m1"
        ma1 := ZLEMA1
        ma1   

    if mav == "ZLEMA" and x == "m2"
        ma2 := ZLEMA2
        ma2

    if mav == "TSF" and x == "m1"
        ma1 := TSF1
        ma1
    
    if mav == "TSF" and x == "m2"
        ma2 := TSF2
        ma2
     
    var float result = na  
    if x == "m1"
        result := ma1
    else 
        result := ma2
        
    result
    

// @function TODO: getMA by @KivancOzbilgic function cutomised
// @param mav TODO: string
// @param src TODO: float 
// @param length TODO: int
// @param DEMA TODO: float
// @param VAR TODO: float
// @param WWMA TODO: float
// @param ZLEMA TODO: float
// @param TSF TODO: float
// @param HMA TODO: float
// @returns TODO: float ZLEMA  
export  getMA2(string mav, float src, simple int length, float DEMA, float VAR, float WWMA, float ZLEMA, float TSF, float HMA) =>
    ma = 0.0
    if mav == 'SMA'
        ma := ta.sma(src, length)
        ma

    if mav == 'EMA'
        ma := ta.ema(src, length)
        ma 

    if mav == 'WMA'
        ma := ta.wma(src, length)
        ma

    if mav == 'DEMA'
        ma := DEMA
        ma

    if mav == 'TMA'
        ma := ta.sma(ta.sma(src, math.ceil(length / 2)), math.floor(length / 2) + 1)
        ma

    if mav == 'VAR'
        ma := VAR
        ma

    if mav == 'WWMA'
        ma := WWMA
        ma

    if mav == 'ZLEMA'
        ma := ZLEMA
        ma

    if mav == 'TSF'
        ma := TSF
        ma

    if mav == 'HULL'
        ma := HMA
        ma
    ma


// @param length TODO: simple int
// @param hLEn TODO: int 
// @param lLen TODO: int
// @param mav TODO: string
// @param percent TODO: float
// @returns TODO: [HOTT, LOTT]
export full_hott_lott(simple int length, int hLen, int lLen, string mav, float percent)=>

    highs           = ta.highest(high, hLen)
    lows            = ta.lowest(low, lLen)

    VAR1            = Var_Func(highs,length)
    WWMA1           = Wwma_Func(highs,length)
    ZLEMA1          = Zlema_Func(highs,length)
    TSF1            = Tsf_Func(highs,length)

    VAR2            = Var_Func(lows,length)
    WWMA2           = Wwma_Func(lows,length)
    ZLEMA2          = Zlema_Func(lows,length)
    TSF2            = Tsf_Func(lows,length)
    MAvg1           = getMA(mav, highs, length, "m1", VAR1, VAR2, WWMA1, WWMA2,  ZLEMA1, ZLEMA2,  TSF1, TSF2)
    fark1           = MAvg1*percent*0.01
    longStop1       = MAvg1 - fark1
    longStopPrev1   = nz(longStop1[1], longStop1)
    longStop1       := MAvg1 > longStopPrev1 ? math.max(longStop1, longStopPrev1) : longStop1
    shortStop1      =  MAvg1 + fark1
    shortStopPrev1  = nz(shortStop1[1], shortStop1)
    shortStop1      := MAvg1 < shortStopPrev1 ? math.min(shortStop1, shortStopPrev1) : shortStop1
    dir1            = 1
    dir1            := nz(dir1[1], dir1)
    dir1            := dir1 == -1 and MAvg1 > shortStopPrev1 ? 1 : dir1 == 1 and MAvg1 < longStopPrev1 ? -1 : dir1
    MT1             = dir1==1 ? longStop1 : shortStop1

    MAvg2           = getMA(mav, lows, length, "m2", VAR1, VAR2, WWMA1, WWMA2,  ZLEMA1, ZLEMA2,  TSF1, TSF2)
    fark2           = MAvg2*percent*0.01
    longStop2       = MAvg2 - fark2
    longStopPrev2   = nz(longStop2[1], longStop2)
    longStop2       := MAvg2 > longStopPrev2 ? math.max(longStop2, longStopPrev2) : longStop2
    shortStop2      =  MAvg2 + fark2
    shortStopPrev2  = nz(shortStop2[1], shortStop2)
    shortStop2      := MAvg2 < shortStopPrev2 ? math.min(shortStop2, shortStopPrev2) : shortStop2
    dir2            = 1
    dir2            := nz(dir2[1], dir2)
    dir2            := dir2 == -1 and MAvg2 > shortStopPrev2 ? 1 : dir2 == 1 and MAvg2 < longStopPrev2 ? -1 : dir2
    MT2             = dir2==1 ? longStop2 : shortStop2

    HOTT            =   MAvg1 > MT1 ? MT1*(200+percent)/200 : MT1*(200-percent)/200
    LOTT            =   MAvg2 > MT2 ? MT2*(200+percent)/200 : MT2*(200-percent)/200

    [HOTT, LOTT]

// #############################          HOTT LOTT         ####################################


// #############################          ATR BANDS         ####################################
getBandOffsetSource(srcIn, isUpperBand) =>
    // Initialize the return to our fail-safe 'close', which is also the default input, then update thru the switch statement
    ret = close
    switch srcIn
        "close" => ret := close
        "wicks" => ret := isUpperBand ? high : low
        => ret := close
    ret

// @function TODO: get ATR function cutomised
// @param atrPeriod TODO: int 
// @param (atrPeriod) TODO: float
// @param atrSourceRef TODO: string
// @returns TODO: [upperATRBand, lowerATRBand]
export getATRBands(simple int atrPeriod, float atrMultiplier, string atrSourceRef) =>
    atr = ta.atr(atrPeriod)
    scaledATR = atr * atrMultiplier
    upperATRBand = getBandOffsetSource(atrSourceRef, true) + scaledATR
    lowerATRBand = getBandOffsetSource(atrSourceRef, false) - scaledATR
    [upperATRBand, lowerATRBand]
// #############################        ATR BANDS END       ####################################

// #############################       ATR TREND BANDS      ####################################
// @function TODO: get ATR function cutomised
// @param src TODO: float 
// @param delta TODO: float
// @returns TODO: [midb, upperb, lowerb]
// @function get trend ATR bands.
export getATRTrendBands(float src, float delta)=>
    float upperb    = 0.0
    float lowerb    = 0.0

    upperb          := nz(upperb[1])
    lowerb          := nz(lowerb[1])

    if src > nz(upperb[1])
        upperb := math.max(nz(upperb[1]), math.max(src, nz(src[1])))
        lowerb := upperb - delta
        if lowerb < nz(lowerb[1]) or lowerb > nz(lowerb[1]) and upperb == nz(upperb[1])
            lowerb := nz(lowerb[1])
    else if src < nz(lowerb[1])
        lowerb := math.min(nz(lowerb[1]), math.min(src, nz(src[1])))
        upperb := lowerb + delta
        if upperb > nz(upperb[1]) or upperb < nz(upperb[1]) and lowerb == nz(lowerb[1]) 
            upperb := nz(upperb[1])
        
    midb = (lowerb + upperb) / 2
    [midb, upperb, lowerb]
// #############################    ATR TREND BANDS END     ####################################

// #############################            RANGIFY           ####################################
// @function TODO: return an array containing up to 21 levels divising a Range
// @param hvalue TODO: float 
// @param lvalue TODO: float
// @param divider TODO: int
// @returns TODO: levels
export rangify(float hvalue, float lvalue, int divider) =>
    var levels      = array.new_float((divider - 1), na)
    diffcentage     = (hvalue - lvalue) / lvalue
    renge_perc      = diffcentage / divider
    loop_limit      = divider  - 1
    indexer         = 0 

    for i = 1 to loop_limit
        lv          = hvalue * ( 1 - (renge_perc * i))
        array.set(levels, indexer, lv)
        indexer     += 1

    levels
// #############################           RANGIFY END        ####################################

                // ==============   BANDS DIVIDERS   ===========================
// @function TODO               : plot up to 21 levels divising a Range
// @param upperb TODO           : float 
// @param lowerb TODO           : float
// @param rg_divider TODO       : int

// @returns TODO: levels
export range_dividers(float upperb, float lowerb, int rg_divider) =>

    // countOccurenceWithinLookback 
    var float rgDivider0            = na
    var float rgDivider1            = na
    var float rgDivider2            = na
    var float rgDivider3            = na
    var float rgDivider4            = na
    var float rgDivider5            = na
    var float rgDivider6            = na
    var float rgDivider7            = na
    var float rgDivider8            = na
    var float rgDivider9            = na
    var float rgDivider10           = na
    var float rgDivider11           = na
    var float rgDivider12           = na
    var float rgDivider13           = na
    var float rgDivider14           = na
    var float rgDivider15           = na
    var float rgDivider16           = na
    var float rgDivider17           = na
    var float rgDivider18           = na
    var float rgDivider19           = na
    var float rgDivider20           = na

    levels                          = rangify(upperb, lowerb, rg_divider)

    rgDivider0                      := rg_divider >= 2  ? array.get(levels, 0)  : na
    rgDivider1                      := rg_divider >= 3  ? array.get(levels, 1)  : na
    rgDivider2                      := rg_divider >= 4  ? array.get(levels, 2)  : na
    rgDivider3                      := rg_divider >= 5  ? array.get(levels, 3)  : na
    rgDivider4                      := rg_divider >= 6  ? array.get(levels, 4)  : na
    rgDivider5                      := rg_divider >= 7  ? array.get(levels, 5)  : na
    rgDivider6                      := rg_divider >= 8  ? array.get(levels, 6)  : na
    rgDivider7                      := rg_divider >= 9  ? array.get(levels, 7)  : na
    rgDivider8                      := rg_divider >= 10 ? array.get(levels, 8)  : na
    rgDivider9                      := rg_divider >= 11 ? array.get(levels, 9)  : na
    rgDivider10                     := rg_divider >= 12 ? array.get(levels, 10) : na
    rgDivider11                     := rg_divider >= 13 ? array.get(levels, 11) : na
    rgDivider12                     := rg_divider >= 14 ? array.get(levels, 12) : na
    rgDivider13                     := rg_divider >= 15 ? array.get(levels, 13) : na
    rgDivider14                     := rg_divider >= 16 ? array.get(levels, 14) : na
    rgDivider15                     := rg_divider >= 17 ? array.get(levels, 15) : na
    rgDivider16                     := rg_divider >= 18 ? array.get(levels, 16) : na
    rgDivider17                     := rg_divider >= 19 ? array.get(levels, 17) : na
    rgDivider18                     := rg_divider >= 20 ? array.get(levels, 18) : na
    rgDivider19                     := rg_divider >= 21 ? array.get(levels, 19) : na
    rgDivider20                     := rg_divider >= 22 ? array.get(levels, 20) : na

    // Plot Range Splitter
    // line.new(x1=showRgSplitter ? bar_index[1] : na, y1=mid_b, x2=showRgSplitter ? bar_index : na, y2=mid_b,        color=color.gray, width=3)


    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider0, x2=showRgDividers ? bar_index : na, y2=rgDivider0, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider1, x2=showRgDividers ? bar_index : na, y2=rgDivider1, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider2, x2=showRgDividers ? bar_index : na, y2=rgDivider2, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider3, x2=showRgDividers ? bar_index : na, y2=rgDivider3, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider4, x2=showRgDividers ? bar_index : na, y2=rgDivider4, color=not darkMode ? color.black : color.white, width=3)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider5, x2=showRgDividers ? bar_index : na, y2=rgDivider5, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider6, x2=showRgDividers ? bar_index : na, y2=rgDivider6, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider7, x2=showRgDividers ? bar_index : na, y2=rgDivider7, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider8, x2=showRgDividers ? bar_index : na, y2=rgDivider8, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider9, x2=showRgDividers ? bar_index : na, y2=rgDivider9, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider10, x2=showRgDividers ? bar_index : na, y2=rgDivider10, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider11, x2=showRgDividers ? bar_index : na, y2=rgDivider11, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider12, x2=showRgDividers ? bar_index : na, y2=rgDivider12, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider13, x2=showRgDividers ? bar_index : na, y2=rgDivider13, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider14, x2=showRgDividers ? bar_index : na, y2=rgDivider14, color=not darkMode ? color.black : color.white, width=3)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider15, x2=showRgDividers ? bar_index : na, y2=rgDivider15, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider16, x2=showRgDividers ? bar_index : na, y2=rgDivider16, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider17, x2=showRgDividers ? bar_index : na, y2=rgDivider17, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider18, x2=showRgDividers ? bar_index : na, y2=rgDivider18, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider19, x2=showRgDividers ? bar_index : na, y2=rgDivider19, color=not darkMode ? color.black : color.white, width=1)
    // line.new(x1=showRgDividers ? bar_index[1] : na, y1=rgDivider20, x2=showRgDividers ? bar_index : na, y2=rgDivider20, color=not darkMode ? color.black : color.white, width=1)

    [levels, rgDivider0, rgDivider1, rgDivider2, rgDivider3, rgDivider4, rgDivider5, rgDivider6, rgDivider7, rgDivider8, rgDivider9, rgDivider10, rgDivider11, rgDivider12, rgDivider13, rgDivider14, rgDivider15, rgDivider16, rgDivider17, rgDivider18, rgDivider19, rgDivider20]

                // ============== ATR BANDS DIVIDERS END ===========================

// #############################            RANGE_MID           ####################################

// @function TODO: return average Range and state value
// @param ha_close TODO: float 
// @param ha_high TODO: float
// @param ha_low TODO: float
// @param darkMode TODO: bool
// @returns TODO: [mid, uppish, downish, midUp, midDn, realb, reals]
export rangeValue(float ha_close, float ha_high, float ha_low, bool darkMode) =>
    float up        = na
    float down      = na
    
    //MID
    up              := ha_close <   nz(up[1]) and ha_close>down[1] ? nz(up[1])      : ha_high
    down            := ha_close <   nz(up[1]) and ha_close>down[1] ? nz(down[1])    : ha_low
    mid             = math.avg(up,down)
    ranje           = (mid-mid[1])/mid[1] * 100
    
    uppish          = up    ==  nz(up[1])   ?   up  :   na
    downish         = down  ==  nz(down[1]) ?   down:   na
    midUp           = mid * (1 + ((uppish - mid) / uppish)/2)
    midDn           = mid * (1 - ((mid - downish) / mid)/2)
    
    
    // --- MID conditions  --- \\\\
    var int mid_state = 0
    buy_mid         = ranje[1]== 0 and ranje > 0 or ranje[1] < 0 and ranje > 0 
    sell_mid        = ranje[1]== 0 and ranje < 0 or ranje[1] > 0 and ranje < 0
    
    if buy_mid
        mid_state := 1
    
    if sell_mid
        mid_state := -1
        
    realb           = buy_mid and mid_state == 1 and mid_state != mid_state[1]
    reals           = sell_mid and mid_state == -1 and mid_state != mid_state[1]
    
    midColor = ranje > 0 ? color.new(color.green, 0) : ranje < 0 ? color.new(color.red, 0) : not darkMode ? color.new(color.black, 0) : color.new(color.white, 0)

    
    [mid, ranje, midColor, mid_state, uppish, downish, midUp, midDn, realb, reals]




// @function TODO: return  posistive / negative variation candle of a serie
// @param serie TODO: float 
// @returns TODO: [variation, state, realb, reals]
export variation_status(float serie) =>
    variation           = (serie - serie[1]) / serie[1] * 100

    var int state = 0
    positive_var    = variation[1]== 0 and variation > 0 or variation[1] < 0 and variation > 0 
    negativ_var     = variation[1]== 0 and variation < 0 or variation[1] > 0 and variation < 0
    
    if positive_var
        state       := 1
    
    if negativ_var
        state       := -1
        
    realb           = positive_var and state == 1  and state != state[1]
    reals           = negativ_var  and state == -1 and state != state[1]
    
    [variation, state, realb, reals, positive_var, negativ_var]
// #############################           RANGE_MID END        ####################################


// @function TODO: getMA by @KivancOzbilgic function cutomised
// @param source TODO: float 
// @param length TODO: int
// @param type TODO: float
// @returns TODO: float ZLEMA 
export SmMA(float source, simple int length, string type) =>
    var m = matrix.new<float>(1, length, 0)
    for i = 0 to length-1
        matrix.set(m, 0, i, source)
    type == "SMA" ? ta.sma(source, length) :
     type == "EMA" ? ta.ema(source, length) :
     type == "SMMA (RMA)" ? ta.rma(source, length) :
     type == "WMA" ? ta.wma(source, length) :
     type == "VWMA" ? ta.vwma(source, length) :
     type == "HMA" ? ta.hma(source, length) :
     type == "ALMA" ? ta.alma(source, length, 0.85, 6) :
     type == "SWMA" ? ta.swma(source) :
     type == "RMA" ? ta.rma(source, length) :
     type == "VWAP" ? ta.vwap(source) :
     type == "LSMA" ? ta.linreg(source, length, 0) :
     na
     
     
     

// #############################            LOOKBACK           ####################################
// @function TODO: Modifiy a boolean to  false if the value for the past leftlookback have changed
// @param value TODO: float 
// @param leftlookback TODO: int
// @returns TODO: nothing
export unchanged_value(int leftlookback, float value) =>
    var changed = false
    for i = 0 to leftlookback - 1
        if value == value[i]
            changed := true
        else
            changed := false
    changed


// @function TODO: Modifiy a boolean to  false if the value for the past leftlookback have changed
// @param cond TODO: bool 
// @param leftlookback TODO: int
// @returns TODO: nothing
export unchanged_condition(int leftlookback, bool cond) =>
    var changed = false
    for i = 0 to leftlookback - 1
        if cond
            changed := true
        else
            changed := false
    changed


// @function TODO: cumulates a series value for the past leftlookback
// @param value TODO: float 
// @param leftlookback TODO: int
// @returns TODO: cummulative total
export cumulative_lookback(int leftlookback, float value) =>
    var float total     = na
    for i = 0 to leftlookback - 1
        total += value
    total

// @function TODO:  cumulates a series value for the past leftlookback depending on a valid and invalid condition
// @param value             TODO: float 
// @param leftlookback      TODO: int
// @param valid_cond        TODO: bool 
// @param invalid_cond      TODO: bool 
// @returns                 TODO: cummulative total
export reseting_cmltv_lookback(int leftlookback, float value, bool invalid_cond, bool valid_cond) =>
    var changed         = false
    var float total     = na

    if invalid_cond
        total           := na

    if valid_cond
        for i = 0 to leftlookback - 1
            total           += value
    total

// @function TODO: Modifiy a boolean to  false if 3 values for the past leftlookback have not changed
// @param value TODO: float 
// @param leftlookback TODO: int
// @returns TODO: nothing
export three_V_unchanged(int leftlookback, float value1, float value2, float value3) =>
    var changed = false
    for  k = 0 to leftlookback
        if value1 == value1[k] and value2 == value2[k] and value3 == value3[k]
            changed := true
        else
            changed := false

    changed
// #############################          LOOKBACK END        ####################################



// ################################ CONDITION OCCURENCE ########################################
// @function TODO: Show Only first occurence depending on another condition
// @param boolean TODO: (Type: bool) 
// @param bool1 TODO: (Type: bool) 
// @param bool1_switchOff_cond TODO: (Type: bool) 
// @param bool2 TODO: (Type: bool) 
// @param bool2_switchOff_cond TODO: (Type: bool) 
// @returns TODO: Filterred [bool1, booll2]
export showOnlyFirstSignal(bool boolean, bool bool1, bool bool1_switchOff_cond, bool bool2, bool bool2_switchOff_cond) =>
    var  int bool1Occured = 0
    var  int bool2Occured = 0
    
    if bool1
        bool1Occured := 1
        
    if bool2
        bool2Occured := 1
        
    if bool1_switchOff_cond
        bool1Occured := 0
    if bool2_switchOff_cond
        bool2Occured := 0
    
    buy     = boolean ? bool1Occured[1] != 1  and bool1Occured == 1 : bool1
    sell    = boolean ? bool2Occured[1] != 1  and bool2Occured == 1 : bool2
    [buy, sell]


// @function Single out the occurence of a bool series between to 2 bool series.
// @param booleanInput to activate or deactivate occurences filtering.
// @returns filterred or not bool series.
export showOnlyFirstOccurence(bool booleanInput, bool buycon, bool sellcond) =>
    var  int buyconOccured = 0
    var  int sellconOccured = 0
    
    if buycon
        buyconOccured := 1
        sellconOccured := -1

    if sellcond
        sellconOccured := 1
        buyconOccured := -1
    
    buy  = booleanInput ? buyconOccured[1] != 1  and buyconOccured == 1  : buycon
    sell = booleanInput ? sellconOccured[1] != 1 and sellconOccured == 1 : sellcond
    [buy, sell]


// @function TODO: find the first occurrence of a condtion depending on a prior condition
// @param priorCond TODO: bool 
// @param cond2 TODO: bool
// @param cond3 TODO: bool decide when we look for first prior condition occurence or not
// @returns TODO: the candle where cond 2 happened
export ConditionedCondition(bool priorCond, bool cond2, bool cond3) =>
    var int priorCond_state         = 0
    var int seconCondition_state    = 0

    if priorCond
        priorCond_state             := 1
        seconCondition_state        := -1   /// -1 : we lookin  second  condition
    
    if cond3   // we not looking anymore
        priorCond_state             := 0
        seconCondition_state        := 0

    if priorCond_state == 1 and seconCondition_state == -1 and cond2 
        seconCondition_state        := 1
        priorCond_state             := 0

    happened                        =  seconCondition_state[1] != 1 and seconCondition_state == 1
    priorHappened                   =  priorCond_state[1] !=1      and priorCond_state == 1

    [happened, priorHappened]




// @function TODO: find the first occurrence or all occurences of a condtion depending on a prior condition
// @param priorCond TODO: bool 
// @param cond2 TODO: bool
// @param singleton TODO: bool
// @returns TODO: the candle where cond 2 happened
export ConditionedFisrtOccurence(bool priorCond, bool cond2, bool singleton) =>
    var int cond2_state         = 0
    
    if singleton
        while priorCond

            if cond2
                cond2_state         := 1

            else
                cond2_state         := 0
    else
        if priorCond and cond2
            cond2_state         := 1
        else
            cond2_state         := 0

    happened                    =  cond2_state[1] != 1 and cond2_state == 1
// ################################ CONDITION OCCURENCE ########################################

// ############################   TWO TRENDZ STATE  ###############################
// @function TODO: return 2 trendz state
// @param long_trigger)  TODO:           bool 
// @param short_trigger  TODO:           bool
// @returns TODO: [long_trend_state, short_trend_state]
export TwoTrendzState( bool long_trigger, bool short_trigger)=>
    var bool long_trend_state       = na
    var bool short_trend_state      = na

    if long_trigger
        long_trend_state            := true
        short_trend_state           := false

    if short_trigger
        long_trend_state            := false
        short_trend_state           := true

    [long_trend_state, short_trend_state]
// ##########################  TWO TRENDZ STATE  END  #############################

// ############################   Line_between_lines from perc  ###############################
// @function TODO: return a line between 2 lines, the line position depend of the percent parameter
// @param hl1 (higher line) TODO:           float 
// @param ll2 (lower line)  TODO:           float
// @param percent           TODO:           float
// @returns TODO: return a line between 2 lines, the line position depend of the percent parameter
export lineBetweenLines(float hl1, float ll2, float percent) =>
    ranje           = ( (hl1 - ll2) / hl1 ) * percent
    line_value      = ll2 * (1 + ranje)
    line_value
// ##########################   Line_between_lines from  perc END  #############################

// ############################   variation_beetweenlines   ###############################
// @function TODO: return a the percent distance between 2 ylines, the line position depend of the percent parameter
// @param hl1 (higher line) TODO:           float 
// @param ll2 (lower line)  TODO:           float
// @returns TODO: return float distance percent
export abs_variation_beetweenlines(float hl1, float ll2) =>
    ranje           = math.abs(( (hl1 - ll2) / hl1 ) * 100)
    ranje
// ##########################   variation_beetweenlines  END  #############################

// ############################   AbsPercentChange  ###############################
// @function TODO: return the variation percent of a serie 
// @param src               TODO:           float
// @returns TODO: return the variation percent of a serie 
export AbsPercentChange(float src) =>
    value = math.abs((src - src[1])/src[1]) * 100
    value
// ##########################   AbsPercentChange END  #############################
// ############################      AbsPercent     ###############################
// @function TODO: return the percent difference between 2 series
// @param src1               TODO:           float
// @param src2               TODO:           float
// @returns TODO: return the variation percent of a serie 
export AbsPercent(float src1, float src2) =>
    distance = math.abs(src1 - src2)  // Calculate the absolute distance
    percentage = (distance / src2) * 100 
// ##########################      AbsPercent END     #############################
// ###################     ConditionedCummulativePercentage   #####################
// @function TODO: return the cummuled variation percent of a serie depending on bool cond
// @param cond1              TODO:           bool
// @param src2               TODO:           float
// @param cond2              TODO:           bool
// @returns TODO: return the cumuled variation percent of a serie 
export CondiCummulPercent(bool cond1, float src, bool cond2) =>
    var float value = 0.0
    if cond1
        value += math.abs((src - src[1])/src[1]) * 100

    if cond2
        value := 0.0
    
    value
// ################     ConditionedCummulativePercentage END  ######################
// ###################     TriggeringConditionedCummulativePercentage   #####################
// @function TODO: return the cummuled variation percent of a serie depending on bool cond
// @param triggeringcond1               TODO:           bool
// @param src2                          TODO:           float
// @param cancelingcond2                TODO:           bool
// @returns TODO: return the cumuled variation percent of a serie 
export trigCondiCummulPercent(bool triggeringcond1, float src, bool resettingcond2) =>
    var float value  = 0.0
    var int state    = 0

    if triggeringcond1
        state       := 1

    if resettingcond2
        state       := -1

    if state == 1
        value       += math.abs((src - src[1])/src[1]) * 100

        if resettingcond2
            state       := -1

    if state == -1
        value       := 0.0

        if triggeringcond1
            state       := 1

    
    value
// ################     TriggeringConditionedCummulativePercentage END  ######################
// ###################     S&R PRICE  #####################
// @function TODO: return the price
// @param _osc               TODO:           float
// @param _thresh            TODO:           float
// @param _cross              TODO:           string
// @returns TODO: return return_1
export f_getPrice(float _osc, float _thresh, string _cross) =>
    avgHigh = math.avg(high, close)
    avgLow  = math.avg(low , close)

    var return_1 = 0.

    if _cross == 'over' or _cross == 'both'
        if ta.crossover(_osc, _thresh)
            return_1 := avgHigh
            return_1
    if _cross == 'under' or _cross == 'both'
        if ta.crossunder(_osc, _thresh)
            return_1 := avgLow
            return_1
    return_1
// ################      S&R PRICE END  ######################
// ###################     ICT_DONCHIAN  #####################
// @returns TODO: return donchian levels
// @param prd               TODO:           int
// @returns TODO: return donchian levels
export ict_donchian(int prd) =>
    // ~~ Variables {
    var Up  = float(na)
    var Dn  = float(na)
    var iUp = int(na)
    var iDn = int(na)
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
    // ~~ Pivots {
    Up   := math.max(Up[1],high)
    Dn   := math.min(Dn[1],low)
    pvtHi = ta.pivothigh(high,prd,prd)
    pvtLo = ta.pivotlow(low,prd,prd)
    if pvtHi
        Up := pvtHi
    if pvtLo
        Dn := pvtLo
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}

    // ~~ Premium & Discount {
    PremiumTop   = Up-(Up-Dn)*.1
    PremiumBot   = Up-(Up-Dn)*.25
    DiscountTop  = Dn+(Up-Dn)*.25
    DiscountBot  = Dn+(Up-Dn)*.1
    MidTop       = Up-(Up-Dn)*.45
    MidBot       = Dn+(Up-Dn)*.45
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
    [Up, Dn, PremiumTop, PremiumBot, DiscountTop, DiscountBot, MidTop, MidBot]
// ################      ICT_DONCHIAN END  ######################


// ###################     Session_ticks  #####################
open_bar(string ses, string ref_res) =>
    t = time(ref_res, ses)
    na(t[1]) and not na(t) or t[1] < t

is_open(ses) =>
    not na(time(timeframe.period, ses))

// @returns TODO: return session h-l
// @param rth_ses               TODO:           string
// @param prcolorid             TODO:           color
// @param ref_res               TODO:           string
// @returns TODO: return donchian levels
export session_tick( string rth_ses , color colori, string ref_res) =>
    rth_open_bar    = open_bar(rth_ses, ref_res)
    rth_is_open     = is_open(rth_ses)


    rth_low         = float(na)
    rth_low         := rth_is_open ? rth_open_bar ? low : math.min(rth_low[1], low) : rth_low[1]
    rth_high        = float(na)
    rth_high        := rth_is_open ? rth_open_bar ? high : math.max(rth_high[1], high) : rth_high[1]
    rth_fill_color  = rth_is_open ? colori : na

    [rth_low, rth_high, rth_fill_color, rth_open_bar, rth_is_open]
// ################      Session_ticks END  ######################

// ###################     is_newbar  #####################
// @returns TODO: rreturn is new bar of timeframe
// @param res               TODO:           string
// @returns TODO: return is new bar of timeframe
export is_newbar(string res) =>
    t = time(res)
    not na(t) and (na(t[1]) or t > t[1])
// ################      is_newbar END  ######################
// ###################     is_newbar  #####################
// @returns TODO: Function to calculate the daily high and low
// @returns TODO: return [float dailyHigh,float  dailyLow]
export getDailyHighLow() =>
    var float dailyHigh = na
    var float dailyLow  = na

    if ta.change(time("D")) != 0
        dailyHigh := high
        dailyLow := low
    else if high > dailyHigh
        dailyHigh := high
    else if low < dailyLow
        dailyLow := low

    [dailyHigh, dailyLow]
// ################      is_newbar END  ######################

// ###################     RSI BANDZ  #####################
// @function TODO: RSI BANDZ
// @param float rsiSourceInput
// @param int rsiLengthInput
// @param int up_level
// @param int dn_level
// @returns TODO: RSI BANDZ DATA [rsi, up_lev_line, dn_lev_line, rsi_range, rsi_line_chart]
export calculateRSI_BANDZ(float rsiSourceInput,int rsiLengthInput, int up_level, int dn_level) =>
    maValue                 = ta.rma(ohlc4, rsiLengthInput)
    up                      = ta.rma(math.max(ta.change(rsiSourceInput), 0), rsiLengthInput)
    down                    = ta.rma(-math.min(ta.change(rsiSourceInput), 0), rsiLengthInput)
    rsi                     = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
    up_lev_line             = ta.rma(ta.highest(rsiLengthInput)[1], rsiLengthInput)
    dn_lev_line             = ta.rma(ta.lowest(rsiLengthInput)[1], rsiLengthInput)
    rsi_range               = (up_lev_line - dn_lev_line) / (up_level - dn_level) * 100
    rsi_line_chart          = maValue + (rsi - 50) / 100 * rsi_range
    [rsi, up_lev_line, dn_lev_line, rsi_range, rsi_line_chart]
// ################      RSI BANDZ END  ######################


// ###################     RTI LVLZ  #####################
// @function TODO: RTI Level
// @param float rsiSourceInput
// @param int trend_sens_percent
// @param int up_level
// @param int dn_level
// @returns TODO: RTI Level [rsi, up_lev_line, dn_lev_line, rsi_range, rsi_line_chart]
export RTI(int trend_sens_percent, int data_count, int signal_length )=>
    upper_trend                     = close + ta.stdev(close, 2)
    lower_trend                     = close - ta.stdev(close, 2)

    upper_array = array.new<float>(0)
    lower_array = array.new<float>(0)
    for i = 0 to data_count - 1 
        upper_array.push(upper_trend[i])
        lower_array.push(lower_trend[i])
    upper_array.sort()
    lower_array.sort()

    upper_index  = math.round(trend_sens_percent / 100 * data_count) - 1
    lower_index  = math.round((100 - trend_sens_percent) / 100 * data_count) - 1
    UpperTrend   = upper_array.get(upper_index)
    LowerTrend   = lower_array.get(lower_index)
    Rti = ((close - LowerTrend) / (UpperTrend - LowerTrend))*100
    MA_Rti = ta.ema(Rti,signal_length)
    [Rti, MA_Rti]
// ################      RSI BANDZ END  ######################


