Signal_transcoder_library
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © djmad
//@version=5

//@description
// sending more than 1 value to the next indicator via plot needs encoding
// via _16bit_encode() you send in 8 bit and plot out via a plot(hidden via display=display.none)
// at the daisychain indicator you input that plot and send it through [x1,x2,x3,....]=_16bit_decode(plotname daisychain) so you get back your 8 bits :-)
// have fun
// Thanks Lonesometheblue for the assistance

library("Signal_transcoder_library")

export _16bit_encode(bool [] mux_array) =>
    float mux = 0
    for int x = 0 to math.min(array.size(mux_array),15)
        mux := mux + math.round(((array.get(mux_array,x) == true)?math.pow(2,x):0),0)

export _16bit_decode(float mux) =>
    int mux_int = math.min(math.ceil(math.round(mux,0)),65535)
    bool solving = true
    int counter = 0
    demux_array = array.new_bool(16, false)
    for x = -15 to 0 by 1
        if (math.floor(mux_int / math.pow(2,x*-1)) > 0)
            mux_int := mux_int - math.ceil(math.pow(2,x*-1))
            array.set(demux_array,-x,true)
        else
            array.set(demux_array,-x,false)
        demux_array

export f_remap_bits(bool [] I_B, bool [] O_B, int [] M_I,int [] M_O) =>
    var int mapfrom = 0
    var int mapto = 0
    for i = 0 to 15 by 1
        mapfrom := array.get(M_I, i)
        mapto := array.get(M_O, i)
        if array.get(M_O, i) > -1 and array.get(M_I, i) > -1
            array.set(O_B, mapto, array.get(I_B, mapfrom))
    0

export f_bool_operations(bool [] I_B, bool [] O_B, int S_1 = -1, int S_2 = -1, int S_3 = -1, int T_1 = -1, string function = 'add') =>
    var bool calc_1 = 0
    var bool calc_2 = 0
    var bool calc_3 = 0  
    
    for i = 0 to 15 by 1
        array.set(O_B, i, array.get(I_B, i))
    
    if  T_1 != -1
        if function == 'and'        //"and", "or", "not", "nand", "nor", "xor", "xnor", "TP", "TPD", "TON", "TOF" ,"MDP", "RATE" 
            if S_1 != -1
                calc_1 := array.get(I_B,S_1)
            else
                calc_1 := true
                
            if S_2 != -1
                calc_2 := array.get(I_B,S_2)
            else
                calc_2 := true
                
            if S_3 != -1
                calc_3 := array.get(I_B,S_3)
            else
                calc_3 := true
        
            if (calc_1 and calc_2 and calc_3)
                array.set(O_B, T_1, true)
            else
                array.set(O_B, T_1, false)
                
        if function == 'or'        //"and", "or", "not", "nand", "nor", "xor", "xnor", "TP", "TPD", "TON", "TOF" ,"MDP", "RATE" 
            if S_1 != -1
                calc_1 := array.get(I_B,S_1)
            else if S_1 == -1
                calc_1 := false
                 
            if S_2 != -1
                calc_2 := array.get(I_B,S_2)
            else if S_2 == -1
                calc_2 := false
                
            if S_3 != -1
                calc_3 := array.get(I_B,S_3)
            else if S_3 == -1
                calc_3 := false
                 
            if (calc_1 or calc_2 or calc_3)
                array.set(O_B, T_1, true)
            else
                array.set(O_B, T_1, false) 

        if function == 'not'        //"and", "or", "not", "nand", "nor", "xor", "xnor", "TP", "TPD", "TON", "TOF" ,"MDP", "RATE" 
            if S_1 != -1
                calc_1 := not array.get(I_B,S_1)
            else if S_1 == -1
                calc_1 := true
            if calc_1
                array.set(O_B, T_1, true)
            else
                array.set(O_B, T_1, false)            

        if function == 'nand'        //"and", "or", "not", "nand", "nor", "xor", "xnor", "TP", "TPD", "TON", "TOF" ,"MDP", "RATE"
            if S_1 != -1
                calc_1 := array.get(I_B,S_1)
            else
                calc_1 := true
                
            if S_2 != -1
                calc_2 := array.get(I_B,S_2)
            else
                calc_2 := true
                
            if S_3 != -1
                calc_3 := array.get(I_B,S_3)
            else
                calc_3 := true
        
            if (calc_1 and calc_2 and calc_3)
                array.set(O_B, T_1, false)
            else
                array.set(O_B, T_1, true)

        if function == 'nor'        //"and", "or", "not", "nand", "nor", "xor", "xnor", "TP", "TPD", "TON", "TOF" ,"MDP", "RATE" 
            if S_1 != -1
                calc_1 := array.get(I_B,S_1)
            else if S_1 == -1
                calc_1 := false
                 
            if S_2 != -1
                calc_2 := array.get(I_B,S_2)
            else if S_2 == -1
                calc_2 := false
                
            if S_3 != -1
                calc_3 := array.get(I_B,S_3)
            else if S_3 == -1
                calc_3 := false
                 
            if (calc_1 or calc_2 or calc_3)
                array.set(O_B, T_1, false)
            else
                array.set(O_B, T_1, true) 

        if function == 'xor'        //"and", "or", "not", "nand", "nor", "xor", "xnor", "TP", "TPD", "TON", "TOF" ,"MDP", "RATE"
            if S_1 != -1
                calc_1 := array.get(I_B,S_1)
            else if S_1 == -1
                calc_1 := false
                 
            if S_2 != -1
                calc_2 := array.get(I_B,S_2)
            else if S_2 == -1
                calc_2 := false
                
            if S_3 != -1
                calc_3 := array.get(I_B,S_3)
            else if S_3 == -1
                calc_3 := false
                 
            if (calc_1 and not calc_2 and not calc_3) or (not calc_1 and calc_2 and not calc_3) or (not calc_1 and not calc_2 and calc_3)
                array.set(O_B, T_1, true)
            else
                array.set(O_B, T_1, false)

        if function == 'xnor'        //"and", "or", "not", "nand", "nor", "xor", "xnor", "TP", "TPD", "TON", "TOF" ,"MDP", "RATE"
            if S_1 != -1
                calc_1 := array.get(I_B,S_1)
            else if S_1 == -1
                calc_1 := false
                 
            if S_2 != -1
                calc_2 := array.get(I_B,S_2)
            else if S_2 == -1
                calc_2 := false
                
            if S_3 != -1
                calc_3 := array.get(I_B,S_3)
            else if S_3 == -1
                calc_3 := false
                 
            if (not calc_1 and not calc_2 and not calc_3) or (calc_1 and calc_2 and calc_3)
                array.set(O_B, T_1, true)
            else
                array.set(O_B, T_1, false) 


        if function == 'TP'        //"and", "or", "not", "nand", "nor", "xor", "xnor", "TP", "TPD", "TON", "TOF" ,"MDP", "RATE"
            var TP_active = false
            if S_1 != -1
                calc_1 := array.get(I_B,S_1)
            else if S_1 == -1
                calc_1 := false
            if calc_1 and TP_active
                array.set(O_B, T_1, false)
            if calc_1 and not TP_active
                array.set(O_B, T_1, true)
                TP_active := true
            else if not calc_1
                array.set(O_B, T_1, false)         
                TP_active := false

        if function == 'TPD'        //"and", "or", "not", "nand", "nor", "xor", "xnor", "TP", "TPD", "TON", "TOF" ,"MDP", "RATE" 
            var TPD_active = false
            var int TPD_time = 0

            if S_1 != -1
                calc_1 := array.get(I_B,S_1)
            else if S_1 == -1
                calc_1 := false

            if calc_1 and TPD_time < S_2
                TPD_time := TPD_time +1
                array.set(O_B, T_1, false)
                0

            if calc_1 and TPD_active and TPD_time >= S_2
                TPD_active := true
                array.set(O_B, T_1, true)
                0
            else if not calc_1
                array.set(O_B, T_1, false)         
                TPD_active := false
                TPD_time := 0
                0

        if function == 'TON'        //"and", "or", "not", "nand", "nor", "xor", "xnor", "TP", "TPD", "TON", "TOF" ,"MDP", "RATE" 
            var TON_active = false
            var int TON_time = -1

            if S_1 != -1
                calc_1 := array.get(I_B,S_1)
            else if S_1 == -1
                calc_1 := false

            if calc_1 and TON_time < S_2
                TON_time := TON_time +1
                array.set(O_B, T_1, false)
                0

            if calc_1 and TON_time >= S_2
                TON_active := true
                array.set(O_B, T_1, true)
                0
            else if not calc_1
                array.set(O_B, T_1, false)         
                TON_active := false
                TON_time := -1
                0

        if function == 'TOF'        //"and", "or", "not", "nand", "nor", "xor", "xnor", "TP", "TPD", "TON", "TOF" ,"MDP", "RATE"
            var TOF_active = false
            var int TOF_time = -2

            if S_1 != -1
                calc_1 := array.get(I_B,S_1)
            else if S_1 == -1
                calc_1 := false
                
            if calc_1
                TOF_active := true
                TOF_time := S_2
                array.set(O_B, T_1, true)
    
            if TOF_active and TOF_time > -2
                TOF_time := TOF_time -1
                array.set(O_B, T_1, true)         

            if TOF_active and TOF_time == -2 and not calc_1
                array.set(O_B, T_1, false)    
                
        if function == 'MDP'        //"and", "or", "not", "nand", "nor", "xor", "xnor", "TP", "TPD", "TON", "TOF" ,"MDP" , "RATE"
            var MDP_up = false
            var MDP_down = false
            var float rememberprice = close
            var int TOF_time = -2

            if S_1 != -1
                calc_1 := array.get(I_B,S_1)
            else if S_1 == -1
                calc_1 := false

            if not calc_1 
                array.set(O_B, T_1, false)

            if calc_1 and MDP_up and MDP_down
                array.set(O_B, T_1, false)

            if rememberprice * (S_2 / 1000) > close or rememberprice * (S_3 / 1000) < close and (MDP_up or MDP_down)
                array.set(O_B, T_1, false)                
                MDP_up := false
                MDP_down := false//

            if calc_1 and (not MDP_up and not MDP_down)
                rememberprice := close
                MDP_up := true
                MDP_down := true
                array.set(O_B, T_1, true)

        if function == 'RATE'        //"and", "or", "not", "nand", "nor", "xor", "xnor", "TP", "TPD", "TON", "TOF" ,"MDP" , "RATE"
            var ratecalc = 0
            var Counterarray = array.new_bool(S_2,false)
            
            if S_1 != -1
                calc_1 := array.get(I_B,S_1)
            else if S_1 == -1
                calc_1 := false

            array.insert(Counterarray,0,array.get(I_B,S_1))
                
            if array.size(Counterarray) > S_2
                array.remove(Counterarray,array.size(Counterarray)-1)
                ratecalc := 0
                for i = 1 to array.size(Counterarray)-1
                    if array.get(Counterarray, i) == true
                        ratecalc := ratecalc +1

            if ratecalc >= S_3
                array.set(O_B, T_1, true)
            else
                array.set(O_B, T_1, false)

infuse(bool [] M, int C, bool S) =>
    if C > -1 and C <=15
        array.set(M, C, S)
    M

export f_infuse_signal(
 int CH_1, bool S_1, 
 bool [] M_O) =>
    infuse(M_O,CH_1, S_1)

export f_infuse_signal(
 int CH_1, bool S_1, 
 int CH_2, bool S_2, 
 bool [] M_O) =>
    infuse(M_O,CH_1, S_1)
    infuse(M_O,CH_2, S_2)

export f_infuse_signal(
 int CH_1, bool S_1, 
 int CH_2, bool S_2, 
 int CH_3, bool S_3, 
 bool [] M_O) =>
    infuse(M_O,CH_1, S_1)
    infuse(M_O,CH_2, S_2)
    infuse(M_O,CH_3, S_3)

export f_infuse_signal(
 int CH_1, bool S_1, 
 int CH_2, bool S_2, 
 int CH_3, bool S_3, 
 int CH_4, bool S_4, 
 bool [] M_O) =>
    infuse(M_O,CH_1, S_1)
    infuse(M_O,CH_2, S_2)
    infuse(M_O,CH_3, S_3)
    infuse(M_O,CH_4, S_4)

export f_infuse_signal(
 int CH_1, bool S_1, 
 int CH_2, bool S_2, 
 int CH_3, bool S_3, 
 int CH_4, bool S_4, 
 int CH_5, bool S_5, 
 bool [] M_O) =>
    infuse(M_O,CH_1, S_1)
    infuse(M_O,CH_2, S_2)
    infuse(M_O,CH_3, S_3)
    infuse(M_O,CH_4, S_4)
    infuse(M_O,CH_5, S_5)

export f_infuse_signal(
 int CH_1, bool S_1, 
 int CH_2, bool S_2, 
 int CH_3, bool S_3, 
 int CH_4, bool S_4, 
 int CH_5, bool S_5, 
 int CH_6, bool S_6, 
 bool [] M_O) =>
    infuse(M_O,CH_1, S_1)
    infuse(M_O,CH_2, S_2)
    infuse(M_O,CH_3, S_3)
    infuse(M_O,CH_4, S_4)
    infuse(M_O,CH_5, S_5)
    infuse(M_O,CH_6, S_6)

export f_infuse_signal(
 int CH_1, bool S_1, 
 int CH_2, bool S_2, 
 int CH_3, bool S_3, 
 int CH_4, bool S_4, 
 int CH_5, bool S_5, 
 int CH_6, bool S_6, 
 int CH_7, bool S_7, 
 bool [] M_O) =>
    infuse(M_O,CH_1, S_1)
    infuse(M_O,CH_2, S_2)
    infuse(M_O,CH_3, S_3)
    infuse(M_O,CH_4, S_4)
    infuse(M_O,CH_5, S_5)
    infuse(M_O,CH_6, S_6)
    infuse(M_O,CH_7, S_7)

export f_infuse_signal(
 int CH_1, bool S_1, 
 int CH_2, bool S_2, 
 int CH_3, bool S_3, 
 int CH_4, bool S_4, 
 int CH_5, bool S_5, 
 int CH_6, bool S_6, 
 int CH_7, bool S_7, 
 int CH_8, bool S_8, 
 bool [] M_O) =>
    infuse(M_O,CH_1, S_1)
    infuse(M_O,CH_2, S_2)
    infuse(M_O,CH_3, S_3)
    infuse(M_O,CH_4, S_4)
    infuse(M_O,CH_5, S_5)
    infuse(M_O,CH_6, S_6)
    infuse(M_O,CH_7, S_7)
    infuse(M_O,CH_8, S_8)

var Mapping_IN                  =           array.new_bool(16,0)
var Mapping_OUT                 =           array.new_bool(16,0)
var WorkBits1                   =           array.new_bool(16, false)
var WorkBits2                   =           array.new_bool(16, false)
var WorkBits3                   =           array.new_bool(16, false)
var WorkBits4                   =           array.new_bool(16, false)
var WorkBits5                   =           array.new_bool(16, false)
var WorkBits6                   =           array.new_bool(16, false)
var WorkBits7                   =           array.new_bool(16, false)
var WorkBits8                   =           array.new_bool(16, false)
var OutputBits                  =           array.new_bool(16, false)


int testzufall          =           math.ceil(math.random(0,65535,53))

Mapping_IN := _16bit_decode(testzufall)

f_bool_operations( Mapping_IN,    WorkBits1,  0, 1, -1, 8,"and")
f_bool_operations( WorkBits1,    WorkBits2,  0, 1, -1, 9,"or")
f_bool_operations( WorkBits2,    WorkBits3,  0, 1, -1, 10,"not")
f_bool_operations( WorkBits3,    WorkBits4,  0, 30, 20, 1,"RATE")

f_bool_operations( WorkBits4,    WorkBits5,  0, 1, -1, 12,"nor")
f_bool_operations( WorkBits5,    WorkBits6,  0, 3, -1, 13,"TP")
f_bool_operations( WorkBits6,    WorkBits7,  0, 2, -1, 14,"TON")
f_bool_operations( WorkBits7,    Mapping_OUT,  0, 995, 1005, 15,"MDP")

plot(array.get(_16bit_decode(_16bit_encode(Mapping_OUT)),0)?2:1.5, style=plot.style_linebr)
plot(array.get(_16bit_decode(_16bit_encode(Mapping_OUT)),1)?4:3.5, style=plot.style_linebr)
plot(array.get(_16bit_decode(_16bit_encode(Mapping_OUT)),2)?6:5.5, style=plot.style_linebr)
plot(array.get(_16bit_decode(_16bit_encode(Mapping_OUT)),3)?8:7.5, style=plot.style_linebr)
plot(array.get(_16bit_decode(_16bit_encode(Mapping_OUT)),4)?10:9.5, style=plot.style_linebr)
plot(array.get(_16bit_decode(_16bit_encode(Mapping_OUT)),5)?12:11.5, style=plot.style_linebr)
plot(array.get(_16bit_decode(_16bit_encode(Mapping_OUT)),6)?14:13.5, style=plot.style_linebr)
plot(array.get(_16bit_decode(_16bit_encode(Mapping_OUT)),7)?16:15.5, style=plot.style_linebr)

plot(array.get(_16bit_decode(_16bit_encode(Mapping_OUT)),8)?22:21.5, style=plot.style_linebr)
plot(array.get(_16bit_decode(_16bit_encode(Mapping_OUT)),9)?24:23.5, style=plot.style_linebr)
plot(array.get(_16bit_decode(_16bit_encode(Mapping_OUT)),10)?26:25.5, style=plot.style_linebr)
plot(array.get(_16bit_decode(_16bit_encode(Mapping_OUT)),11)?28:27.5, style=plot.style_linebr)
plot(array.get(_16bit_decode(_16bit_encode(Mapping_OUT)),12)?30:29.5, style=plot.style_linebr)
plot(array.get(_16bit_decode(_16bit_encode(Mapping_OUT)),13)?32:31.5, style=plot.style_linebr)
plot(array.get(_16bit_decode(_16bit_encode(Mapping_OUT)),14)?34:33.5, style=plot.style_linebr)
plot(array.get(_16bit_decode(_16bit_encode(Mapping_OUT)),15)?36:35.5, style=plot.style_linebr)

plot(-10+_16bit_encode(_16bit_decode(testzufall))/6500,color=color.green)
plot(-10+testzufall[1]/6500,color=color.yellow)
