15m Candle Tool
// 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('15m Candle Tool', shorttitle='15mCandleTool', overlay=true, precision=2, max_lines_count = 500, max_boxes_count = 500)

fteenbars = input.int(defval=10, title='# of 15m Bars on Display', minval=0, maxval=240, group = "15 Minute Candles")
green = input(defval=color.rgb(139, 255, 50, 55), title='        Up Color', group = "15 Minute Candles", inline = "2")
red = input(defval=color.rgb(255, 84, 50, 55), title='     Down Color', group = "15 Minute Candles", inline = "2")

lvl1_tog = input.bool(true, title = "Lvl 1", group = "measurments", inline = "1", tooltip = "How levels are drawn:\nGreen Candle = High(0.00) to Low(1.00)\nRed Candle = Low(0.00) to High(1.00)")
lvl1 = input.float(0.382, step = 0.01, title = "", group = "measurments", inline = "1")
lvl1_style = input.string(". . .", title = "", options = ["___","- - -",". . ."], group = "measurments", inline = "1")

lvl2_tog = input.bool(true, title = "Lvl 2", group = "measurments", inline = "2")
lvl2 = input.float(0.5, title = "", step = 0.01, group = "measurments", inline = "2")
lvl2_style = input.string("- - -", title = "", options = ["___","- - -",". . ."], group = "measurments", inline = "2")

lvl3_tog = input.bool(true, title = "Lvl 3", group = "measurments", inline = "3")
lvl3 = input.float(0.618, title = "", step = 0.01, group = "measurments", inline = "3")
lvl3_style = input.string(". . .", title = "", options = ["___","- - -",". . ."], group = "measurments", inline = "3")

display_5 = input.bool(true, title = "5 Minute  ", group = "Display Countdowns", inline = "1")
color_5 = input.color(color.rgb(255, 84, 50), title = "", group = "Display Countdowns", inline = "1")
style_5 = input.string(". . .", title = "", options = ["___","- - -",". . ."], group = "Display Countdowns", inline = "1")
disp_5 = input.bool(false, title = "Display Line?", group = "Display Countdowns", inline = "1")

display_15 = input.bool(true, title = "15 Minute ", group = "Display Countdowns", inline = "2")
color_15 = input.color(color.rgb(50, 204, 255), title = "", group = "Display Countdowns", inline = "2")
style_15 = input.string("- - -", title = "", options = ["___","- - -",". . ."], group = "Display Countdowns", inline = "2")
disp_15 = input.bool(false, title = "Display Line?", group = "Display Countdowns", inline = "2")

display_hour = input.bool(true, title = "1 Hour     ", group = "Display Countdowns", inline = "3")
color_60 = input.color(color.rgb(139, 255, 50), title = "", group = "Display Countdowns", inline = "3")
style_60 = input.string("___", title = "", options = ["___","- - -",". . ."], group = "Display Countdowns", inline = "3")
disp_60 = input.bool(false, title = "Display Line?", group = "Display Countdowns", inline = "3")

linestyle(_input) =>
    _input == "___"?line.style_solid:
     _input == "- - -"?line.style_dashed:
     _input == ". . ."?line.style_dotted:
     na


tf_check = timeframe.isminutes and (timeframe.multiplier == 1 or timeframe.multiplier == 3 or timeframe.multiplier == 5)

if tf_check == false
    runtime.error("Please Use 1, 3, or 5 Minute chart.")

tf = timeframe.multiplier
tf60 = 60 / tf
tf15 = 15 / tf
tf5 = 5 / tf

o15 = tf == 1 ? open[15] : tf == 3 ? open[5] : tf == 5 ? open[3] : na
c15 = tf == 1 ? close[1] : tf == 3 ? close[1] : tf == 5 ? close[1] : na

hourcheck = timeframe.change("60")
fivecheck = timeframe.change("5")
fteencheck = timeframe.change("15")

barsback = fteenbars * (15 / tf)

var ftlow = close
var fthigh = close
if high > fthigh
    fthigh := high
if low < ftlow
    ftlow := low
if fteencheck
    ftlow := low
    fthigh := high

var line l = display_hour and disp_60?line.new(x1=bar_index + tf60, y1=close + 1, x2=bar_index + tf60, y2=close + 2, color=color_60, style=linestyle(style_60), extend=extend.both):na
if hourcheck and disp_60
    line.set_x1(l,bar_index + tf60)
    line.set_x2(l,bar_index + tf60)
    line.set_y1(l,close + 1)
    line.set_y2(l,close + 2)
var line z = display_5 and disp_5?line.new(x1=bar_index + tf5, y1=close + 1, x2=bar_index + tf5, y2=close + 2, color=color_5, style=linestyle(style_5), extend=extend.both):na
if fivecheck and disp_5
    line.set_x1(z,bar_index + tf5)
    line.set_x2(z,bar_index + tf5)
    line.set_y1(z,close + 1)
    line.set_y2(z,close + 2)

anchor = o15 < c15 ? fthigh[1] : ftlow[1]

seg = fthigh[1] - ftlow[1]
s5line = anchor + seg * (o15 < c15 ? -lvl1 : lvl1)
f0line = anchor + seg * (o15 < c15 ? -lvl2 : lvl2)
t5line = anchor + seg * (o15 < c15 ? -lvl3 : lvl3)

rg = o15 < c15 ? green : red

var line x = display_15 and disp_15?line.new(x1=bar_index + tf15, y1=close + 1, x2=bar_index + tf15, y2=close + 2, color=color_15, style=linestyle(style_15), extend=extend.both):na
var b = box.new(left=bar_index - 15 / tf, top=o15, right=bar_index - 1, bottom=c15, bgcolor=rg, border_color=rg)
var line fw1 = na
var line fw2 = na
var line fh = line.new(x1=bar_index - 15 / tf, y1=fthigh[1], x2=bar_index + tf15, y2=fthigh[1], color=color.new(rg,0), width=2)
var line fl = line.new(x1=bar_index - 15 / tf, y1=ftlow[1], x2=bar_index + tf15, y2=ftlow[1], color=color.new(rg,0), width=2)
var line fha = na
var line fla = na
var line fma = na
var line s5 = lvl1_tog?line.new(x1=bar_index - 15 / tf, y1=s5line, x2=bar_index + tf15 + 1, y2=s5line, color=color.rgb(255, 255, 255),style=linestyle(lvl1_style)):na
var line f0 = lvl2_tog?line.new(x1=bar_index - 15 / tf, y1=f0line, x2=bar_index + tf15 + 1, y2=f0line, color=color.rgb(255, 255, 255),style=linestyle(lvl2_style)):na
var line t5 = lvl3_tog?line.new(x1=bar_index - 15 / tf, y1=t5line, x2=bar_index + tf15 + 1, y2=t5line, color=color.rgb(255, 255, 255),style=linestyle(lvl3_style)):na

if fteencheck
    if disp_15
        line.set_x1(x,bar_index + tf15)
        line.set_x2(x,bar_index + tf15)
        line.set_y1(x,close + 1)
        line.set_y2(x,close + 2)
    if lvl1_tog
        line.set_x1(s5,bar_index - 15 / tf)
        line.set_x2(s5,bar_index + tf15)
        line.set_y1(s5,s5line)
        line.set_y2(s5,s5line)
    if lvl2_tog
        line.set_x1(f0,bar_index - 15 / tf)
        line.set_x2(f0,bar_index + tf15)
        line.set_y1(f0,f0line)
        line.set_y2(f0,f0line)
    if lvl3_tog
        line.set_x1(t5,bar_index - 15 / tf)
        line.set_x2(t5,bar_index + tf15)
        line.set_y1(t5,t5line)
        line.set_y2(t5,t5line)
    line.set_x1(fh,bar_index - 15 / tf)
    line.set_x2(fh,bar_index + tf15)
    line.set_y1(fh,fthigh[1])
    line.set_y2(fh,fthigh[1])
    line.set_color(fh,rg)    
    line.set_x1(fl,bar_index - 15 / tf)
    line.set_x2(fl,bar_index + tf15)
    line.set_y1(fl,ftlow[1])
    line.set_y2(fl,ftlow[1])
    line.set_color(fl,rg)
    fw1 := line.new(x1=bar_index - 15 / tf / 2, y1=math.max(o15,c15), x2=bar_index - 15 / tf / 2, y2=fthigh[1], color=color.new(rg,0))
    fw2 := line.new(x1=bar_index - 15 / tf / 2, y1=math.min(o15,c15), x2=bar_index - 15 / tf / 2, y2=ftlow[1], color=color.new(rg,0))
    b := box.new(left=bar_index - 15 / tf, top=o15, right=bar_index - 1, bottom=c15, bgcolor=rg, border_color=rg)
    box.delete(b[barsback])
    line.delete(fw1[barsback])
    line.delete(fw2[barsback])


bar_secs = (tf * 60)                                                            // How many seconds in a bar
hourcount = (60 / tf) - ta.barssince(hourcheck)                                 // How many bars in an hour - Number of bars lapsed = How many bars left in hour
sec = math.floor((timenow - time) / 1000)                                       // (Current time - Bar start time) / 1000 = Number of Seconds since Bar start
seccount = bar_secs - sec                                                       // How many seconds in a bar - seconds since bar start = seconds left in bar
mins = math.floor(seccount / 60)                                                // Seconds left in bar / 60 = Minutes left in bar
secs = seccount - (mins * 60)                                                   // Seconds left in bar - (minutes left in bar*60) = Seconds left until next minute  
untilhour = (mins + (secs * .01)) + ((hourcount * tf) - tf)                     // (Minutes left in bar + Seconds left until next minute*0.01) + bars left in hour*  timeframe)
untilfteen = untilhour - math.floor(untilhour / 15) * 15                        //
untilfive = untilhour - math.floor(untilhour / 5) * 5                           //


tablesize = input.string('normal', ' Table Size', inline='1', options=['small', 'normal', 'large','huge'], group = "Countdown Table")
horz = input.bool(false, title = "Use Flat Display?", group = "Countdown Table", inline = "1")
tableYpos = input.string('middle', 'Position   ', inline='2', options=['top', 'middle', 'bottom'], group = "Countdown Table")
tableXpos = input.string('right', '', inline='2', options=['left', 'center', 'right'], group = "Countdown Table")



var table table1 = table.new(tableYpos + '_' + tableXpos, 3, 6)

add_zero(_input) =>
    _input == 0? "00":
     _input == 1? "01":
     _input == 2? "02":
     _input == 3? "03":
     _input == 4? "04":
     _input == 5? "05":
     _input == 6? "06":
     _input == 7? "07":
     _input == 8? "08":
     _input == 9? "09":
     str.tostring(_input)

timeform(_input) =>
    place1 = math.floor(_input)
    place2 = (_input - math.floor(_input))*100
    add_zero(place1) + ":" + add_zero(place2)


titlesize(_input) =>
    tablesize == "huge"?"large":
     tablesize == "large"?"normal":
     tablesize == "normal"?"small":
     tablesize == "small"?"tiny":na

if barstate.islast and display_5
    if horz
        table.cell(table1,0,0, text = "5 Min", text_color = color_5, text_size = titlesize(tablesize))
        table.cell(table1,0,1, text = session.islastbar?"Market\nClosed":timeform(untilfive), text_color = color_5, text_size = tablesize)
    if horz == false
        table.cell(table1,0,0, text = "5 Min", text_color = color_5, text_size = titlesize(tablesize))
        table.cell(table1,0,1, text = session.islastbar?"Market\nClosed":timeform(untilfive), text_color = color_5, text_size = tablesize)
if barstate.islast and display_15    
    if horz
        table.cell(table1,1,0, text = "15 Min", text_color = color_15, text_size = titlesize(tablesize))
        table.cell(table1,1,1, text = session.islastbar?"Market\nClosed":timeform(untilfteen), text_color = color_15, text_size = tablesize)
    if horz == false
        table.cell(table1,0,2, text = "15 Min", text_color = color_15, text_size = titlesize(tablesize))
        table.cell(table1,0,3, text = session.islastbar?"Market\nClosed":timeform(untilfteen), text_color = color_15, text_size = tablesize)
if barstate.islast and display_hour    
    if horz
        table.cell(table1,2,0, text = "1 Hour", text_color = color_60, text_size = titlesize(tablesize))
        table.cell(table1,2,1, text = session.islastbar?"Market\nClosed":timeform(untilhour), text_color = color_60, text_size = tablesize)
    if horz == false
        table.cell(table1,0,4, text = "1 Hour", text_color = color_60, text_size = titlesize(tablesize))
        table.cell(table1,0,5, text = session.islastbar?"Market\nClosed":timeform(untilhour), text_color = color_60, text_size = tablesize)
