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

//@version=5

// @description This library helps with drawing indicators and candle charts on all timeframes.
library('MTF_Drawings', overlay = true)

//
// CANDLE DRAWING
//

// @function Populates two arrays with drawing data of the HTF candles.
// @param BarsBack Bars number to display.
// @param BodyBear Candle body bear color.
// @param BodyBull Candle body bull color.
// @param BordersBear Candle border bear color.
// @param BordersBull Candle border bull color.
// @param WickBear Candle wick bear color.
// @param WickBull Candle wick bull color.
// @param LineStyle Wick style (Solid-Dotted-Dashed).
// @param BoxStyle Border style (Solid-Dotted-Dashed).
// @param LineWidth Wick width.
// @param HTF_Open HTF open price.
// @param HTF_High HTF high price.
// @param HTF_Low HTF low price.
// @param HTF_Close HTF close price.
// @param HTF_Bar_Index HTF bar_index.
// @returns Two arrays with drawing data of the HTF candles.
export HTF_Candle(int BarsBack, color BodyBear, color BodyBull, color BordersBear, color BordersBull, color WickBear, color WickBull, string LineStyle, string BoxStyle, int LineWidth, float HTF_Open, float HTF_High, float HTF_Low, float HTF_Close, int HTF_Bar_Index) =>
    var box[] Box = array.new<box>(0)
    var line[] Line = array.new<line>(0)
    [Body, Border, Wick] = if HTF_Close < HTF_Open
        [BodyBear, BordersBear, WickBear]
    else
        [BodyBull, BordersBull, WickBull]
    if HTF_Bar_Index[1] != HTF_Bar_Index
        Box.unshift(box.new(na, HTF_Close, na, HTF_Open, Border, border_style = BoxStyle, bgcolor = Body))
        Line.unshift(line.new(na, HTF_High, na, HTF_Low, color = Wick, style = LineStyle, width = LineWidth))
    if Box.size() > 0
        Box.get(0).set_top(HTF_Close)
        Box.get(0).set_bottom(HTF_Open)
        Line.get(0).set_y1(HTF_High)
        Line.get(0).set_y2(HTF_Low)
    if Box.size() > BarsBack 
        box.delete(Box.pop())
        line.delete(Line.pop())
    [Box, Line]

// @function Populates two arrays with drawing data of the LTF candles.
// @param BarsBack Bars number to display.
// @param BodyBear Candle body bear color.
// @param BodyBull Candle body bull color.
// @param BordersBear Candle border bear color.
// @param BordersBull Candle border bull color.
// @param WickBear Candle wick bear color.
// @param WickBull Candle wick bull color.
// @param LineStyle Wick style (Solid-Dotted-Dashed).
// @param BoxStyle Border style (Solid-Dotted-Dashed).
// @param LineWidth Wick width.
// @param LTF_Open LTF open price.
// @param LTF_High LTF high price.
// @param LTF_Low LTF low price.
// @param LTF_Close LTF close price.
// @returns Two arrays with drawing data of the LTF candles.
export LTF_Candle(int BarsBack, color BodyBear, color BodyBull, color BordersBear, color BordersBull, color WickBear, color WickBull, string LineStyle, string BoxStyle, int LineWidth, float[] LTF_Open, float[] LTF_High, float[] LTF_Low, float[] LTF_Close) =>  
    var box[] Box = array.new<box>(0)
    var line[] Line = array.new<line>(0)
    for i = 0 to LTF_Open.size() > 0 ? LTF_Open.size() - 1 : na by 1
        [Body, Border, Wick] = if LTF_Close.get(i) < LTF_Open.get(i) 
            [BodyBear, BordersBear, WickBear]
        else
            [BodyBull, BordersBull, WickBull]
        Box.unshift(box.new(na, LTF_Close.get(i), na,  LTF_Open.get(i), Border, border_style = BoxStyle, bgcolor = Body))
        Line.unshift(line.new(na, LTF_High.get(i), na, LTF_Low.get(i), color = Wick, style = LineStyle, width = LineWidth))
        if Box.size() > BarsBack
            box.delete(Box.pop())
            line.delete(Line.pop())
    [Box, Line]

// @function Draws HTF or LTF candles.
// @param Box Box array with drawing data.
// @param Line Line array with drawing data.
// @param Offset Offset of the candles.
// @returns Drawing of the candles.
export Draw_Candle(box[] Box, line [] Line, int Offset) =>
    if barstate.islast
        for i = 0 to Box.size() > 0 ? Box.size() - 1 : na by 1
            Box.get(i).set_left(bar_index - i * 3 - 1 + Offset)
            Box.get(i).set_right(bar_index - i * 3 + 1 + Offset)
            Line.get(i).set_x1(bar_index - i * 3 + Offset)
            Line.get(i).set_x2(bar_index - i * 3 + Offset)
    [Box, Line]

//
// INDICATOR DRAWING
//

//
// SINGLE LINE
//

// @function Populates one array with drawing data of the HTF indicator.
// @param IndValue Indicator value.
// @param BarsBack Indicator lines to display.
// @param IndColor Indicator color.
// @param HTF_Bar_Index HTF bar_index.
// @returns An array with drawing data of the HTF indicator.
export Populate_HTF_Ind(float IndValue, int BarsBack, color IndColor, int HTF_Bar_Index) =>
    var line[] Line = array.new<line>(0)
    if HTF_Bar_Index[1] != HTF_Bar_Index
        Line.unshift(line.new(na, na, na, IndValue, color = IndColor, width = 1))
    if Line.size() > 0
        Line.get(0).set_y2(IndValue)
    if Line.size() > BarsBack + 1
        line.delete(Line.pop())
    Line

// @function Populates one array with drawing data of the LTF indicator.
// @param IndValue Indicator value.
// @param BarsBack Indicator lines to display.
// @param IndColor Indicator color.
// @returns An array with drawing data of the LTF indicator.
export Populate_LTF_Ind(float[] IndValue, int BarsBack, color IndColor) =>
    var line[] Line = array.new<line>(0)
    for i = 0 to IndValue.size() > 0 ? IndValue.size() - 1 : na by 1
        Line.unshift(line.new(na, na, na, IndValue.get(i), color = IndColor, width = 1))
        if Line.size() > BarsBack + 1
            line.delete(Line.pop())
    Line

// @function Draws one HTF or LTF indicator.
// @param Line Line array with drawing data.
// @param Mult Coordinates multiplier.
// @param Exe Display the indicator.
// @returns Drawing of the indicator.
export Draw_Ind(line[] Line, int Mult, bool Exe) =>
    if Exe and barstate.islast
        for i = 1 to Line.size() > 0 ? Line.size() - 1 : na by 1
            Line.get(i).set_x1(bar_index - i * Mult + Mult)
            Line.get(i).set_x2(bar_index - i * Mult)
            Line.get(i).set_y1(Line.get(i - 1).get_y2())
    Line


//
// DOUBLE LINE
//

// @function Populates two arrays with drawing data of the HTF indicators.
// @param IndValue_1 First indicator value.
// @param IndValue_2 Second indicator value.
// @param BarsBack Indicator lines to display.
// @param IndColor_1 First indicator color.
// @param IndColor_2 Second indicator color.
// @param HTF_Bar_Index HTF bar_index.
// @returns Two arrays with drawing data of the HTF indicators.
export Populate_HTF_Ind_D(float IndValue_1, float IndValue_2, int BarsBack, color IndColor_1, color IndColor_2, int HTF_Bar_Index) =>
    var line[] Line_1 = array.new<line>(0)
    var line[] Line_2 = array.new<line>(0)
    if HTF_Bar_Index[1] != HTF_Bar_Index
        Line_1.unshift(line.new(na, na, na, IndValue_1, color = IndColor_1, width = 1))
        Line_2.unshift(line.new(na, na, na, IndValue_2, color = IndColor_2, width = 1))
    if Line_1.size() > 0
        Line_1.get(0).set_y2(IndValue_1)
        Line_2.get(0).set_y2(IndValue_2)
    if Line_2.size() > BarsBack + 1
        line.delete(Line_1.pop())
        line.delete(Line_2.pop())
    [Line_1, Line_2]


// @function Populates two arrays with drawing data of the LTF indicators.
// @param IndValue_1 First indicator value.
// @param IndValue_2 Second indicator value.
// @param BarsBack Indicator lines to display.
// @param IndColor_1 First indicator color.
// @param IndColor_2 Second indicator color.
// @returns Two arrays with drawing data of the LTF indicators.
export Populate_LTF_Ind_D(float[] IndValue_1, float[] IndValue_2, int BarsBack, color IndColor_1, color IndColor_2) =>
    var line[] Line_1 = array.new<line>(0)
    var line[] Line_2 = array.new<line>(0)
    for i = 0 to IndValue_1.size() > 0 ? IndValue_2.size() - 1 : na by 1
        Line_1.unshift(line.new(na, na, na, IndValue_1.get(i), color = IndColor_1, width = 1))
        Line_2.unshift(line.new(na, na, na, IndValue_2.get(i), color = IndColor_2, width = 1))
        if Line_2.size() > BarsBack + 1
            line.delete(Line_1.pop())
            line.delete(Line_2.pop())
    [Line_1, Line_2]


// @function Draws two LTF or HTF indicators.
// @param Line_1 First line array with drawing data.
// @param Line_2 Second line array with drawing data.
// @param Mult Coordinates multiplier.
// @param Exe_1 Display the first indicator.
// @param Exe_2 Display the second indicator.
// @returns Drawings of the indicators.
export Draw_Ind_D(line[] Line_1, line[] Line_2, int Mult, bool Exe_1, bool Exe_2) =>
    if barstate.islast
        for i = 1 to Line_1.size() > 0 ? Line_2.size() - 1 : na by 1
            if Exe_1
                Line_1.get(i).set_x1(bar_index - i * Mult + Mult)
                Line_1.get(i).set_x2(bar_index - i * Mult)
                Line_1.get(i).set_y1(Line_1.get(i - 1).get_y2())
            if Exe_2
                Line_2.get(i).set_x1(bar_index - i * Mult + Mult)
                Line_2.get(i).set_x2(bar_index - i * Mult)
                Line_2.get(i).set_y1(Line_2.get(i - 1).get_y2())
    [Line_1, Line_2]

//
// CUSTOM COLOR
//

// @function Colors the candles based on indicators output.
// @param Box Candle box array.
// @param Line Candle line array.
// @param BarColor Indicator color array.
// @returns Colored candles.
export Barcolor(box[] Box, line[] Line, color[] BarColor) =>
    for i = 0 to Line.size() > 0 ? Line.size() - 1 : na by 1
        Box.get(i).set_bgcolor(BarColor.get(i))
        Box.get(i).set_border_color(BarColor.get(i))
        Line.get(i).set_color(BarColor.get(i))

// @function Populates two array with drawing data of the HTF indicators with color based on: IndValue_1 >= IndValue_2 ? BullColor : BearColor.
// @param IndValue_1 First indicator value.
// @param IndValue_2 Second indicator value.
// @param BarsBack Indicator lines to display.
// @param BullColor Bull color.
// @param BearColor Bear color.
// @param IndColor_1 First indicator color.
// @param HTF_Bar_Index HTF bar_index.
// @returns Three arrays with drawing and color data of the HTF indicators.
export Populate_HTF_Ind_D_CC(float IndValue_1, float IndValue_2, int BarsBack, color BullColor, color BearColor, color IndColor_1, int HTF_Bar_Index) =>
    var line[] Line_1 = array.new<line>(0)
    var line[] Line_2 = array.new<line>(0)
    var color[] IndColorAY = array.new<color>(0)
    IndColor_0 = IndValue_1 >= IndValue_2 ? BullColor : BearColor
    if HTF_Bar_Index[1] != HTF_Bar_Index
        IndColorAY.unshift(IndColor_0)
        Line_1.unshift(line.new(na, na, na, IndValue_1, color = IndColor_0, width = 1))
        Line_2.unshift(line.new(na, na, na, IndValue_2, color = IndColor_1, width = 1))
    if Line_1.size() > 0
        Line_1.get(0).set_y2(IndValue_1)
        Line_2.get(0).set_y2(IndValue_2)
    if Line_2.size() > BarsBack + 1
        line.delete(Line_1.pop())
        line.delete(Line_2.pop())
        IndColorAY.pop()
    [Line_1, Line_2, IndColorAY]


// @function Populates two arrays with drawing data of the LTF indicators with color based on: IndValue_1 >= IndValue_2 ? BullColor : BearColor.
// @param IndValue_1 First indicator value.
// @param IndValue_2 Second indicator value.
// @param BarsBack Indicator lines to display.
// @param BullColor Bull color.
// @param BearColor Bearcolor.
// @param IndColor_1 First indicator color.
// @returns Three arrays with drawing and color data of the LTF indicators.
export Populate_LTF_Ind_D_CC(float[] IndValue_1, float[] IndValue_2, int BarsBack, color BullColor, color BearColor, color IndColor_1) =>
    var line[] Line_1 = array.new<line>(0)
    var line[] Line_2 = array.new<line>(0)
    var color[] IndColorAY = array.new<color>(0)
    for i = 0 to IndValue_1.size() > 0 ? IndValue_2.size() - 1 : na by 1
        IndColor_0 = IndValue_1.get(i) >= IndValue_2.get(i) ? BullColor : BearColor
        IndColorAY.unshift(IndColor_0)
        Line_1.unshift(line.new(na, na, na, IndValue_1.get(i), color = IndColor_0, width = 1))
        Line_2.unshift(line.new(na, na, na, IndValue_2.get(i), color = IndColor_1, width = 1))
        if Line_2.size() > BarsBack + 1
            line.delete(Line_1.pop())
            line.delete(Line_2.pop())
            IndColorAY.pop()
    [Line_1, Line_2, IndColorAY]

// @function Populates one array with drawing data of the HTF histogram with color based on: IndValue_1 >= IndValue_2 ? BullColor : BearColor.
// @param HistValue Indicator value.
// @param IndValue_1 First indicator value.
// @param IndValue_2 Second indicator value.
// @param BarsBack Indicator lines to display.
// @param BullColor Bull color.
// @param BearColor Bearcolor.
// @param HTF_Bar_Index HTF bar_index
// @returns Two arrays with drawing and color data of the HTF histogram.
export Populate_HTF_Hist_CC(float HistValue, float IndValue_1, float IndValue_2, int BarsBack, color BullColor, color BearColor, int HTF_Bar_Index) =>
    var box[] Box = array.new<box>(0)
    var color[] IndColorAY = array.new<color>(0)
    HistColor = IndValue_1 >= IndValue_2 ? BullColor : BearColor
    if HTF_Bar_Index[1] != HTF_Bar_Index
        IndColorAY.unshift(HistColor)
        Box.unshift(box.new(na, HistValue, na,  0, HistColor, 3, border_style = line.style_solid, bgcolor = HistColor))
    if Box.size() > 0
        Box.get(0).set_top(HistValue)
        Box.get(0).set_bottom(0)
    if Box.size() > BarsBack + 1
        box.delete(Box.pop())
        IndColorAY.pop()
    [Box, IndColorAY]


// @function Populates one array with drawing data of the LTF histogram with color based on: IndValue_1 >= IndValue_2 ? BullColor : BearColor.
// @param HistValue Indicator value.
// @param IndValue_1 First indicator value.
// @param IndValue_2 Second indicator value.
// @param BarsBack Indicator lines to display.
// @param BullColor Bull color.
// @param BearColor Bearcolor.
// @returns Two array with drawing and color data of the LTF histogram.
export Populate_LTF_Hist_CC(float[] HistValue, float[] IndValue_1, float[] IndValue_2, int BarsBack, color BullColor, color BearColor) =>
    var box[] Box = array.new<box>(0)
    var color[] IndColorAY = array.new<color>(0)
    for i = 0 to HistValue.size() > 0 ? HistValue.size() - 1 : na by 1
        HistColor = IndValue_1.get(i) >= IndValue_2.get(i) ? BullColor : BearColor
        IndColorAY.unshift(HistColor)
        Box.unshift(box.new(na, HistValue.get(i), na,  0, HistColor, 3, border_style = line.style_solid, bgcolor = HistColor))
        if Box.size() > BarsBack + 1
            box.delete(Box.pop())
            IndColorAY.pop()
    [Box, IndColorAY]

// @function Populates one array with drawing data of the LTF histogram with color based on: HistValue >= Value ? BullColor : BearColor.
// @param HistValue Indicator value.
// @param Value First indicator value.
// @param BarsBack Indicator lines to display.
// @param BullColor Bull color.
// @param BearColor Bearcolor.
// @returns Two array with drawing and color data of the LTF histogram.
export Populate_LTF_Hist_CC_VA(float[] HistValue, float Value, int BarsBack, color BullColor, color BearColor) =>
    var box[] Box = array.new<box>(0)
    var color[] IndColorAY = array.new<color>(0)
    for i = 0 to HistValue.size() > 0 ? HistValue.size() - 1 : na by 1
        HistColor = HistValue.get(i) >= Value ? BullColor : BearColor
        IndColorAY.unshift(HistColor)
        Box.unshift(box.new(na, HistValue.get(i), na,  0, HistColor, 3, border_style = line.style_solid, bgcolor = HistColor))
        if Box.size() > BarsBack + 1
            box.delete(Box.pop())
            IndColorAY.pop()
    [Box, IndColorAY]

// @function Populates one array with drawing data of the HTF indicator with color based on: IndValue >= IndValue_1 ? BullColor : BearColor.
// @param IndValue Indicator value.
// @param IndValue_1 Second indicator value.
// @param BarsBack Indicator lines to display.
// @param BullColor Bull color.
// @param BearColor Bearcolor.
// @param HTF_Bar_Index HTF bar_index
// @returns Two arrays with drawing and color data of the HTF indicator.
export Populate_HTF_Ind_CC(float IndValue, float IndValue_1, int BarsBack, color BullColor, color BearColor, int HTF_Bar_Index) =>
    var line[] Line = array.new<line>(0)
    var color[] IndColorAY = array.new<color>(0)
    if HTF_Bar_Index[1] != HTF_Bar_Index
        IndColor_0 = IndValue >= IndValue_1 ? BullColor : BearColor
        IndColorAY.unshift(IndColor_0)
        Line.unshift(line.new(na, na, na, IndValue, color = IndColor_0, width = 1))
    if Line.size() > 0
        Line.get(0).set_y2(IndValue)
    if Line.size() > BarsBack + 1
        line.delete(Line.pop())
        IndColorAY.pop()
    [Line, IndColorAY]

// @function Populates one array with drawing data of the LTF indicator with color based on: IndValue >= IndValue_1 ? BullColor : BearColor.
// @param IndValue Indicator value.
// @param IndValue_1 Second indicator value.
// @param BarsBack Indicator lines to display.
// @param BullColor Bull color.
// @param BearColor Bearcolor.
// @returns Two arrays with drawing and color data of the LTF indicator.
export Populate_LTF_Ind_CC(float[] IndValue, float[] IndValue_1, int BarsBack, color BullColor, color BearColor) =>
    var line[] Line = array.new<line>(0)
    var color[] IndColorAY = array.new<color>(0)
    for i = 0 to IndValue.size() > 0 ? IndValue.size() - 1 : na by 1
        IndColor_0 = IndValue.get(i) >= IndValue_1.get(i) ? BullColor : BearColor
        IndColorAY.unshift(IndColor_0)
        Line.unshift(line.new(na, na, na, IndValue.get(i), color = IndColor_0, width = 1))
        if Line.size() > BarsBack + 1
            line.delete(Line.pop())
            IndColorAY.pop()
    [Line, IndColorAY]

//
// LINES AND LINEFILLS
//

// @function Draws price lines on indicators.
// @param BarsBack Indicator lines to display.
// @param y1 Coordinates of the first line.
// @param y2 Coordinates of the second line.
// @param LineType Line type.
// @param Fill Fill color.
// @returns Drawing of the lines.
export Draw_Lines(int BarsBack, float y1, float y2, string LineType, color Fill) =>
    if barstate.islast
        L1 = line.new(bar_index - BarsBack, y1, bar_index, y1, xloc.bar_index, extend.right, color = color.white, style = LineType)
        L2 = line.new(bar_index - BarsBack, y2, bar_index, y2, xloc.bar_index, extend.right, color = color.white, style = LineType)
        L3 = linefill.new(L1, L2, color = Fill)
        line.delete(L1[1]), line.delete(L2[1]), linefill.delete(L3[1])

// @function Fills two lines with linefill HTF or LTF.
// @param Upper Upper line.
// @param Lower Lower line.
// @param BarsBack Indicator lines to display.
// @param FillColor Fill color.
// @returns Linefill of the lines.
export LineFill(line[] Upper, line[] Lower, int BarsBack, color FillColor) =>
    linefill[] LineFill = array.new<linefill>(0)
    for i = 0 to Upper.size() > 0 ? Lower.size() - 1 : na by 1
        LineFill.unshift(linefill.new(Upper.get(i), Lower.get(i), color = FillColor))
        if LineFill.size() > BarsBack
            linefill.delete(LineFill.pop())

//
// HISTOGRAM
//

// @function Populates one array with drawing data of the LTF histogram.
// @param HistValue Indicator value.
// @param BarsBack Indicator lines to display.
// @param HistColor Indicator color.
// @returns One array with drawing data of the LTF histogram.
export Populate_LTF_Hist(float[] HistValue, int BarsBack, color HistColor) =>
    var box[] Box = array.new<box>(0)
    for i = 0 to HistValue.size() > 0 ? HistValue.size() - 1 : na by 1
        Box.unshift(box.new(na, HistValue.get(i), na,  0, HistColor, 3, border_style = line.style_solid, bgcolor = HistColor))
        if Box.size() > BarsBack + 1
            box.delete(Box.pop())
    Box

// @function Populates one array with drawing data of the HTF histogram.
// @param HistValue Indicator value.
// @param BarsBack Indicator lines to display.
// @param HistColor Indicator color.
// @param HTF_Bar_Index HTF bar_index.
// @returns One array with drawing data of the HTF histogram.
export Populate_HTF_Hist(float HistValue, int BarsBack, color HistColor, int HTF_Bar_Index) =>
    var box[] Box = array.new<box>(0)
    if HTF_Bar_Index[1] != HTF_Bar_Index
        Box.unshift(box.new(na, HistValue, na,  0, HistColor, 3, border_style = line.style_solid, bgcolor = HistColor))
    if Box.size() > 0
        Box.get(0).set_top(HistValue)
        Box.get(0).set_bottom(0)
    if Box.size() > BarsBack + 1
        box.delete(Box.pop())
    Box

// @function Draws HTF or LTF histogram.
// @param Box Box Array.
// @param Mult Coordinates multiplier.
// @param Exe Display the histogram.
// @returns Drawing of the histogram.
export Draw_Hist(box[] Box, int Mult, bool Exe) =>
    if Exe and barstate.islast
        for i = 0 to Box.size() > 0 ? Box.size() - 1 : na by 1
            Box.get(i).set_left(bar_index - i * Mult)
            Box.get(i).set_right(bar_index - i * Mult)
    Box