Opening Range with Infinite Price Targets
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © SamRecio

//@version=5
indicator("Opening Range with Infinite Price Targets",shorttitle = "|OR|", overlay = true, max_labels_count = 500, max_lines_count = 500, max_bars_back = 5000)

tog_hist = input.bool(false,"Display Historical Data?", inline = "1", group = "Settings")
start_hour = input.int(9,minval = 0,maxval = 23, group = "Range Time", title ="Start Time:", inline = "1")
start_min = input.int(30,minval = 0,maxval = 59, group = "Range Time", title ="", inline = "1")
end_hour = input.int(9,minval = 0,maxval = 23, group = "Range Time", title = "End Time:  ", inline = "2")
end_min = input.int(45,minval = 0,maxval = 59, group = "Range Time", title ="", inline = "2")
target_p = input.float(50,title = "                      Price Target %", minval = 0, tooltip = "Percent(%) of Range to use for Price Targets.")*0.01

color1 = input.color(#0c3299, title = "High", group = "Colors", inline = "1")
color2 = input.color(#0c3299, title = "Low", group = "Colors", inline = "1")
color3 = input.color(#3179f5, title = "Mean", group = "Colors", inline = "1")
colorf = input.color(color.new(#3179f5,95), title = "Fill", group = "Colors", inline = "1")
colorg = color.rgb(0,255,0)
colorr = color.rgb(255,0,0)
color4 = input.color(#bbd9fb, title = "Targets", group = "Colors", inline = "2")


start_time = start_hour + (start_min*0.01)
end_time = end_hour + (end_min*0.01)

    
t_time = hour + (minute*0.01)
get_or(_start_time,_end_time) =>
    var float or_hi = na
    var float or_lo = na
    or_t = (t_time >= start_time and t_time < end_time)
    or_f = or_t == false
    or_o = or_t and not or_t[1]
    if or_o
        or_hi := high
        or_lo := low
    if or_t and high > or_hi
        or_hi := high
    if or_t and low < or_lo
        or_lo := low
    [or_hi,or_lo,or_t,or_f,or_o]

[or_high,or_low,or_true,or_false,or_open] = get_or(start_time,end_time)

or_range = or_high - or_low
or_mean = math.avg(or_high,or_low)
or_end = or_false and (or_false[1] == false)
eod = (ta.valuewhen(or_open,bar_index,0) - ta.valuewhen(or_end,bar_index,1)) - 1
ba_or = ta.valuewhen(or_end,bar_index,0) 

var long_count = 0
var short_count = 0
if or_open
    long_count := 0
    short_count := 0

pt_step = or_range*target_p
pt_1 = or_high + pt_step
pt_1b = or_low - pt_step
pt_2 = or_high + pt_step*2
pt_2b = or_low - pt_step*2

var float pt_x1 = na
var float pt_x2 = na
var int scount = na
var int lcount = na
var line l1 = na
var line l2 = na
var line l3 = na
var line l4 = na
var line l5 = na
var line l6 = na
var line l7 = na
var line lx = na
var label lab1 = na
var label lab2 = na
var label pt1 = na
var label pt2 = na
var label pt3 = na
var label pt4 = na
var label ptx = na
if or_true
    scount := 1
    lcount := 1
if or_end
    pt_x1 := or_high + pt_step
    pt_x2 := or_low - pt_step
    if tog_hist == false
        a_allLines = line.all
        if array.size(a_allLines) > 0
            for i = 0 to array.size(a_allLines) - 1
                line.delete(array.get(a_allLines, i))
        a_allLabels = label.all
        if array.size(a_allLabels) > 0
            for i = 0 to array.size(a_allLabels) - 1
                label.delete(array.get(a_allLabels, i))
    l1 := line.new(ba_or,or_high,ba_or + eod, or_high, color = color1, width = 2)
    l2 := line.new(ba_or,or_low,ba_or + eod, or_low, color = color2, width = 2)
    l3 := line.new(ba_or,or_mean,ba_or + eod, or_mean, color = color3)
    l4 := line.new(ba_or,pt_x1,ba_or + eod, pt_x1, color = color4, style = line.style_dotted)
    pt1 := label.new(ba_or + eod + 1, pt_x1, style = label.style_label_left, text = "PT1", tooltip = str.tostring(str.format("{0, number, currency}",math.round(pt_x1,2))), textcolor = color4, color = color.new(color4,100), size = size.tiny)
    l5 := line.new(ba_or,pt_x2,ba_or + eod, pt_x2, color = color4, style = line.style_dotted)   
    pt2 := label.new(ba_or + eod + 1, pt_x2, style = label.style_label_left, text = "PT1", tooltip = str.tostring(str.format("{0, number, currency}",math.round(pt_x2,2))), textcolor = color4, color = color.new(color4,100), size = size.tiny)
linefill.new(l1, l2,colorf)
//One a Day Alerts
alertcondition(close > or_high and close[1] <= or_high and or_false and long_count == 0,title = "First Break Above Range")
alertcondition(close < or_low and close[1] >= or_low and or_false and short_count == 0, title = "First Break Below Range")
//Breakout Alerts
alertcondition(close > or_high and close[1] <= or_high and or_false,title = "Break Above Range")
alertcondition(close < or_low and close[1] >= or_low and or_false, title = "Break Below Range")
//BREAKOUT LABELS///////////////////////////////////////////////////////////////

if close > or_high and close[1] <= or_high and or_false and long_count == 0
    lab1 := label.new(bar_index,or_high, style = label.style_triangleup, size = size.auto, color = colorg, yloc = yloc.abovebar)
    long_count := 1

if close < or_low and close[1] >= or_low and or_false and short_count == 0
    lab2 := label.new(bar_index,or_low, style = label.style_triangledown, size = size.auto, color = colorr, yloc = yloc.belowbar)
    short_count := 1
////////////////////////////////////////////////////////////////////////////////
//To infinity and beyond!//////////////////////////////////////////////////////

alertcondition(close > pt_x1 and or_false, title = "New Long PT Hit")    
if close > pt_x1 and or_false 
    lcount := math.floor((close - or_high)/pt_step) + 1
    for i = (lcount[1] + 1) to lcount
        pt_x1 := or_high + (i*pt_step)
        lx := line.new(bar_index,pt_x1,ba_or + eod, pt_x1, color = color4) 
        ptx := label.new(ba_or + eod + 1,pt_x1, style = label.style_label_left, text = "PT" + str.tostring(i), tooltip = str.tostring(str.format("{0, number, currency}",math.round(pt_x1,2))), textcolor = color4, color = color.new(color4,100), size = size.tiny)

alertcondition(close < pt_x2 and or_false, title = "New Short PT Hit")
if close < pt_x2 and or_false
    scount := math.floor((or_low - close)/pt_step) + 1
    for i = (scount[1] + 1) to scount
        pt_x2  := or_low - (i*pt_step)
        lx := line.new(bar_index,pt_x2, ba_or + eod, pt_x2, color = color4)   
        ptx := label.new(ba_or + eod + 1,pt_x2, style = label.style_label_left, text = "PT" + str.tostring(i), tooltip = str.tostring(str.format("{0, number, currency}",math.round(pt_x2,2))), textcolor = color4, color = color.new(color4,100), size = size.tiny)


plot(or_high, title = "OR High", display  = display.none, editable = false)
plot(or_mean, title = "OR Mean", display  = display.none, editable = false)
plot(or_low, title = "OR Low", display  = display.none, editable = false)