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

//@version=5
indicator( "Market Structure", overlay = true, max_bars_back = 5000, max_lines_count = 500, max_labels_count = 500, max_boxes_count = 500)

//#region[Inputs]
_showST = input.bool(true, title = "Short Term", inline = "1")
_stColor = input.color(color.black, "", inline = "1")
_showIT = input.bool(true, title = "Intermediate Term", inline = "2")
_itColor = input.color(color.orange, "", inline = "2")
_showLT = input.bool(true, title = "Long Term", inline = "3")
_ltColor = input.color(color.green, "", inline = "3")
//#endregion

//#region[Functions and Methods]
method oldSwing(array<label> a, type) =>
    if type == "high"
        label.get_y(a.get(a.size()-1)) < label.get_y(a.get(a.size()-2)) and
         label.get_y(a.get(a.size()-2)) > label.get_y(a.get(a.size()-3))

    else if type == 'low'
        label.get_y(a.get(a.size()-1)) > label.get_y(a.get(a.size()-2)) and
         label.get_y(a.get(a.size()-2)) < label.get_y(a.get(a.size()-3))

         
ict_SwingStructure(array<label> stA, bool showST,
                   array<label> itA, bool showIT,
                   array<label> ltA, bool showLT,
                   type) =>
    color cNONE = color.new(color.white, 100)
    int swing   = na
    float price = na
    string lbl  = na
    string _yloc = na
    string lblText = "" 


    if type == "high"
        swing := ta.highestbars(3)
        price := high[1]
        lbl   := label.style_label_down
        lblText := "▼"
        _yloc := yloc.price
    else if type == "low"
        swing := ta.lowestbars(3)
        price := low[1],
        lblText := "▲"
        lbl   := label.style_label_up
        _yloc := yloc.price

    if swing == -1
        stA.push(label.new(bar_index-1, price, lblText, color = cNONE, style = lbl, yloc = _yloc, textcolor = showST ? _stColor : na, size= size.normal))

    if stA.size() > 2
        if stA.oldSwing(type)
            it = label.copy(stA.get(stA.size()-2))
            label.set_textcolor(it, showIT ? _itColor : na)
            if not(itA.size() > 0)
                itA.push(it)
            else if label.get_y(itA.get(itA.size()-1)) != label.get_y(it)
                itA.push(it)

    if itA.size() > 2
        if itA.oldSwing(type)
            lt = label.copy(itA.get(itA.size()-2))
            label.set_textcolor(lt, showLT ? _ltColor : na)
            if not(ltA.size() > 0)
                ltA.push(lt)
            else if label.get_y(ltA.get(ltA.size()-1)) != label.get_y(lt)
                ltA.push(lt)

ict_SimpleMarketStructure(array<label> stH, array<label> stL, bool showST,
                          array<label> itH, array<label> itL, bool showIT,
                          array<label> ltH, array<label> ltL, bool showLT) =>
    
    ict_SwingStructure(stH, showST,
                       itH, showIT,
                       ltH, showLT,
                       "high")
    ict_SwingStructure(stL, showST,
                       itL, showIT,
                       ltL, showLT,
                       "low")

//#endregion

//#region[Logic]
var label[] stHigh = array.new<label>()
var label[] itHigh = array.new<label>()
var label[] ltHigh = array.new<label>()

var label[] stLow = array.new<label>()
var label[] itLow = array.new<label>()
var label[] ltLow = array.new<label>()

ict_SimpleMarketStructure(stHigh, stLow, _showST,
                          itHigh, itLow, _showIT,
                          ltHigh, ltLow, _showLT)
//#endregion