Liquidity Sweeps and Raids
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © pmk07 - who is absolute Stud. Made MTF
// © Cancamurria
// @version=5
indicator(title ="Canca`s Sweeps`n`Raids", overlay=true,max_bars_back=4999, max_lines_count = 500, max_labels_count = 500)

var index = if (3 % 2 != 0)
    math.ceil(float(3) / 2) - 1
else
    math.round(float(3) / 2) - 1

history = input.int(999, "History", minval=10, maxval=4999, group='General')
sweepType = input.string(defval='Wick Only', title="Type", options=['Regular', 'Wick Only'], group='General')
enable_clear = input.bool(true, "Delete broken", group='General')
s_style = input.string(defval='Dotted', title="Style", options=['Solid', 'Dotted', 'Dashed'], group='Lines')
lineStyle = s_style == 'Dotted' ? line.style_dotted : s_style == 'Dashed' ? line.style_dashed : line.style_solid
lineWidth = input.int(1, "Width", group='Lines')
BullColor = input.color(defval=#2195f3, title='Bullish', group='Lines')
BearColor = input.color(defval=#ff0000, title='Bearish', group='Lines')
enable_label = input.bool(true, title= "Labels", group='Labels')
LabelColor = input.color(defval=color.gray, title='Color', group='Labels')
LabelSize = input.string(defval=size.small, title="Size", options=[size.huge, size.large, size.small, size.tiny, size.auto, size.normal], group='Labels')

type sweep
    float lvl = na // y1 and y2
    int start = na // time
    int stop = na // time
    int tf = na // TF in minutes

type plot
    line line = na
    label label = na
    bool isbull = na // true = bull and false = bear
    int tf = na

var plot[] lines  = array.new <plot>()

tf1 = input.bool(true, "1", group='Timeframe')
tf2 = input.bool(true, "3", group='Timeframe')
tf3 = input.bool(true, "5", group='Timeframe')
tf4 = input.bool(false, "15", group='Timeframe')
tf5 = input.bool(false, "30", group='Timeframe')
tf6 = input.bool(false, "45", group='Timeframe')
tf7 = input.bool(true, "60", group='Timeframe')
tf8 = input.bool(false, "120", group='Timeframe')
tf9 = input.bool(false, "180", group='Timeframe')
tf10 = input.bool(false, "240", group='Timeframe')
tf11 = input.bool(true, "D", group='Timeframe')
tf12 = input.bool(false, "W", group='Timeframe')

find_lines(string sweepType, int t) =>
    sweep bearishSweep = na
    sweep bullishSweep = na
    float thresholdSwingLow = na
    float thresholdSwingHigh = na
    for index = 1 to history by 1
        if high[index] >= thresholdSwingHigh or na(thresholdSwingHigh)
            thresholdSwingHigh := high[index]
        if high[index] >= high or thresholdSwingHigh >= high
            break
        if high[index + 1] <= high[index] and high[index - 1] <= high[index] and high >= high[index] and open <= high[index] and high[index] >= thresholdSwingHigh
            if sweepType == 'Regular' or (sweepType == 'Wick Only' and close < high[index])
                bearishSweep := sweep.new(high[index], time - t * 60000 * index, time + t * 60000, t)
    for index = 1 to history by 1
        if low[index] <= thresholdSwingLow or na(thresholdSwingLow)
            thresholdSwingLow := low[index]
        if low[index] <= low or thresholdSwingLow <= low
            break
        if low[index + 1] >= low[index] and low[index - 1] >= low[index] and low <= low[index] and open >= low[index] and low[index] <= thresholdSwingLow
            if sweepType == 'Regular' or (sweepType == 'Wick Only' and close > low[index])
                bullishSweep := sweep.new(low[index], time - t * 60000 * index, time + t * 60000, t)                 
    [bearishSweep, bullishSweep]

remove_lastline(plot[] lines)=>
    sz = array.size(lines)
    if sz >= 100
        temp = array.get(lines, 0)
        line.delete(temp.line)
        if enable_label
            label.delete(temp.label)
            array.remove(lines, 0)


get_txt(tf)=>
    string out = na
    if tf != timeframe.multiplier
        out := switch tf
            1 => "1"
            3 => "3"
            5 => "5"
            15 => "15"
            30 => "30"
            45 => "45"
            60 => "60"
            120 => "120"
            180 => "180"
            240 => "240"
            1440 => "D"
            10080 => "W"
            => "XXX" 
    out

create_lines(sweep bearishSweep, sweep bullishSweep, int tf) =>
    currentTF = timeframe.multiplier
    if not na(bearishSweep) and tf >= currentTF
        remove_lastline(lines)
        label temp_label = na
        if enable_label
            temp_label := label.new(bearishSweep.stop, bearishSweep.lvl, get_txt(bearishSweep.tf), xloc.bar_time, yloc.price, na, label.style_none, LabelColor, LabelSize)
        temp_line = line.new(bearishSweep.start, bearishSweep.lvl, bearishSweep.stop, bearishSweep.lvl, xloc=xloc.bar_time, color=BearColor, style=lineStyle, width=lineWidth)
        array.push(lines, plot.new(temp_line, temp_label, false, bearishSweep.tf))
    if not na(bullishSweep) and tf >= currentTF
        remove_lastline(lines)
        label temp_label = na
        if enable_label
            temp_label := label.new(bullishSweep.stop, bullishSweep.lvl, get_txt(bullishSweep.tf), xloc.bar_time, yloc.price, na, label.style_none, LabelColor, LabelSize)
        temp_line = line.new(bullishSweep.start, bullishSweep.lvl, bullishSweep.stop, bullishSweep.lvl, xloc=xloc.bar_time, color=BullColor, style=lineStyle, width=lineWidth)
        array.push(lines, plot.new(temp_line, temp_label, true, bullishSweep.tf))

control_lines(plot[] lines)=>
    sz = array.size(lines)
    id = array.new_int()
    if sz > 0
        for index = sz - 1 to 0 by 1
            temp = array.get(lines, index)
            tf = temp.tf
            if timeframe.change(get_txt(tf))
                line = temp.line
                lineLvl = line.get_y1(line)
                isbull = temp.isbull
                if (isbull == true and high < lineLvl) or ( isbull == false and low > lineLvl)
                    if enable_label
                        label.delete(temp.label)
                        line.delete(line)
                        array.set(lines, index, na)
                        array.push(id, index)
        if array.size(id) > 0
            array.sort(id, order.ascending)
            for index = array.size(id) - 1 to 0 by 1
                array.remove(lines, array.get(id, index))

[bearishSweep1, bullishSweep1]    = request.security(syminfo.tickerid, "1",   find_lines(sweepType, 1),     barmerge.gaps_off,  barmerge.lookahead_off)
[bearishSweep2, bullishSweep2]    = request.security(syminfo.tickerid, "3",   find_lines(sweepType, 3),     barmerge.gaps_off,  barmerge.lookahead_off)
[bearishSweep3, bullishSweep3]    = request.security(syminfo.tickerid, "5",   find_lines(sweepType, 5),     barmerge.gaps_off,  barmerge.lookahead_off)
[bearishSweep4, bullishSweep4]    = request.security(syminfo.tickerid, "15",  find_lines(sweepType, 15),    barmerge.gaps_off,  barmerge.lookahead_off)
[bearishSweep5, bullishSweep5]    = request.security(syminfo.tickerid, "30",  find_lines(sweepType, 30),    barmerge.gaps_off,  barmerge.lookahead_off)
[bearishSweep6, bullishSweep6]    = request.security(syminfo.tickerid, "45",  find_lines(sweepType, 45),    barmerge.gaps_off,  barmerge.lookahead_off)
[bearishSweep7, bullishSweep7]    = request.security(syminfo.tickerid, "60",  find_lines(sweepType, 60),    barmerge.gaps_off,  barmerge.lookahead_off)
[bearishSweep8, bullishSweep8]    = request.security(syminfo.tickerid, "120", find_lines(sweepType, 120),   barmerge.gaps_off,  barmerge.lookahead_off)
[bearishSweep9, bullishSweep9]    = request.security(syminfo.tickerid, "180", find_lines(sweepType, 180),   barmerge.gaps_off,  barmerge.lookahead_off)
[bearishSweep10, bullishSweep10]  = request.security(syminfo.tickerid, "240", find_lines(sweepType, 240),   barmerge.gaps_off,  barmerge.lookahead_off)
[bearishSweep11, bullishSweep11]  = request.security(syminfo.tickerid, "D",   find_lines(sweepType, 1440),  barmerge.gaps_off,  barmerge.lookahead_off)
[bearishSweep12, bullishSweep12]  = request.security(syminfo.tickerid, "W",   find_lines(sweepType, 10080), barmerge.gaps_off,  barmerge.lookahead_off)

currentTF = timeframe.multiplier
if tf1 and currentTF <= 1
    create_lines(bearishSweep1, bullishSweep1, 1)
if tf2 and currentTF <= 3
    create_lines(bearishSweep2, bullishSweep2, 3)
if tf3 and currentTF <= 5
    create_lines(bearishSweep3, bullishSweep3, 5)
if tf4 and currentTF <= 15
    create_lines(bearishSweep4, bullishSweep4, 15)
if tf5 and currentTF <= 30
    create_lines(bearishSweep5, bullishSweep5, 30)
if tf6 and currentTF <= 45
    create_lines(bearishSweep6, bullishSweep6, 45)
if tf7 and currentTF <= 60
    create_lines(bearishSweep7, bullishSweep7, 60)
if tf8 and currentTF <= 120
    create_lines(bearishSweep8, bullishSweep8, 120)
if tf9 and currentTF <= 180
    create_lines(bearishSweep9, bullishSweep9, 180)
if tf10 and currentTF <= 240
    create_lines(bearishSweep10, bullishSweep10, 240)
if tf11 and currentTF <= 1440
    create_lines(bearishSweep11, bullishSweep11, 1440)
if tf12 and currentTF <= 10080
    create_lines(bearishSweep12, bullishSweep12, 10080)

if enable_clear
    control_lines(lines)

// Define alert conditions for each timeframe
SweepAlert1  = (na(bearishSweep1)  ? false : true) or (na(bullishSweep1)  ? false : true) 
SweepAlert2  = (na(bearishSweep2)  ? false : true) or (na(bullishSweep2)  ? false : true) 
SweepAlert3  = (na(bearishSweep3)  ? false : true) or (na(bullishSweep3)  ? false : true) 
SweepAlert4  = (na(bearishSweep4)  ? false : true) or (na(bullishSweep4)  ? false : true) 
SweepAlert5  = (na(bearishSweep5)  ? false : true) or (na(bullishSweep5)  ? false : true) 
SweepAlert6  = (na(bearishSweep6)  ? false : true) or (na(bullishSweep6)  ? false : true) 
SweepAlert7  = (na(bearishSweep7)  ? false : true) or (na(bullishSweep7)  ? false : true) 
SweepAlert8  = (na(bearishSweep8)  ? false : true) or (na(bullishSweep8)  ? false : true) 
SweepAlert9  = (na(bearishSweep9)  ? false : true) or (na(bullishSweep9)  ? false : true) 
SweepAlert10 = (na(bearishSweep10) ? false : true) or (na(bullishSweep10) ? false : true) 
SweepAlert11 = (na(bearishSweep11) ? false : true) or (na(bullishSweep11) ? false : true) 
SweepAlert12 = (na(bearishSweep12) ? false : true) or (na(bullishSweep12) ? false : true)
SweepAlert13 = (na(bearishSweep1)  ? false : true) or (na(bullishSweep1)  ? false : true) or (na(bearishSweep2) ? false : true) or (na(bullishSweep2) ? false : true) or (na(bearishSweep3) ? false : true) or (na(bullishSweep3) ? false : true) or (na(bearishSweep4) ? false : true) or (na(bullishSweep4) ? false : true) or (na(bearishSweep5) ? false : true) or (na(bullishSweep5) ? false : true) or (na(bearishSweep6) ? false : true) or (na(bullishSweep6) ? false : true) or (na(bearishSweep7) ? false : true) or (na(bullishSweep7) ? false : true) or (na(bearishSweep8) ? false : true) or (na(bullishSweep8) ? false : true) or (na(bearishSweep9) ? false : true) or (na(bullishSweep9) ? false : true) or (na(bearishSweep10) ? false : true) or (na(bullishSweep10) ? false : true) or (na(bearishSweep11) ? false : true) or (na(bullishSweep11) ? false : true) or (na(bearishSweep12) ? false : true) or (na(bullishSweep12) ? false : true)

alertcondition(SweepAlert13, title="All timeframes", message="Sweep has occurred!")
alertcondition(SweepAlert1,  title="1",              message="1 minute sweep has occurred!") 
alertcondition(SweepAlert2,  title="3",              message="3 minutes sweep has occurred!") 
alertcondition(SweepAlert3,  title="5",              message="5 minutes sweep has occurred!") 
alertcondition(SweepAlert4,  title="15",             message="15 minutes sweep has occurred!") 
alertcondition(SweepAlert5,  title="30",             message="30 minutes sweep has occurred!") 
alertcondition(SweepAlert6,  title="45",             message="45 minutes sweep has occurred!") 
alertcondition(SweepAlert7,  title="60",             message="Hourly sweep has occurred!") 
alertcondition(SweepAlert8,  title="2H",             message="2H sweep has occurred!") 
alertcondition(SweepAlert9,  title="3H",             message="3H sweep has occurred!") 
alertcondition(SweepAlert10, title="4H",             message="4H sweep has occurred!") 
alertcondition(SweepAlert11, title="D",              message="Daily sweep has occurred!") 
alertcondition(SweepAlert12, title="W",              message="Weekly sweep has occurred!")
