OHLC 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("OHLC Tool",shorttitle = "📏", overlay = true, max_bars_back = 5000)

//User Inputs
lb = input.int(1, title = "Lookback", minval = 0, maxval = 1000, step = 1, tooltip = "Displays Data from [Input] Bars Ago.\n0 = Current Bar\n1 = Previous Bar\n\nNote: Errors will appear when trying to get data from a bar before your chart's available data. This can be cause by too high of a timeframe along with too high of a lookback, Lowering either will resolve these issues.", group = "[General Settings]")
tf = input.timeframe("", title = "Timeframe", tooltip = "Only Use Higher Timeframes than the Current Chart. \nUsing a Lower Timeframe than your Chart's Timeframe is likely to produce Inaccurate Data!\n\nTip: It is reccomended to only input timeframes that are multiples of your current chart's timeframe so that the line origins align with the bars.", group = "[General Settings]")
open_color = input.color(color.orange, title = "Open", inline = "o_1", group = "[Line Display Settings]     Color | Style | Width")
open_style = input.string(". . .", title = "", options = ["___","- - -",". . ."], group = "[Line Display Settings]     Color | Style | Width", inline = "o_1")
open_thickness = input.int(1, minval = 1, title = "", group = "[Line Display Settings]     Color | Style | Width", inline = "o_1")
high_color = input.color(color.green, title = "High ", inline = "h_1", group = "[Line Display Settings]     Color | Style | Width")
high_style = input.string("- - -", title = "", options = ["___","- - -",". . ."], group = "[Line Display Settings]     Color | Style | Width", inline = "h_1")
high_thickness = input.int(1, minval = 1, title = "", group = "[Line Display Settings]     Color | Style | Width", inline = "h_1")
low_color = input.color(color.red, title = "Low  ", inline = "l_1", group = "[Line Display Settings]     Color | Style | Width")
low_style = input.string("- - -", title = "", options = ["___","- - -",". . ."], group = "[Line Display Settings]     Color | Style | Width", inline = "l_1")
low_thickness = input.int(1, minval = 1, title = "", group = "[Line Display Settings]     Color | Style | Width", inline = "l_1")
close_color = input.color(color.aqua, title = "Close", inline = "c_1", group = "[Line Display Settings]     Color | Style | Width")
close_style = input.string(". . .", title = "", options = ["___","- - -",". . ."], group = "[Line Display Settings]     Color | Style | Width", inline = "c_1")
close_thickness = input.int(1, minval = 1, title = "", group = "[Line Display Settings]     Color | Style | Width", inline = "c_1")

//Pulling OHLC Data for the Timeframe Requested
[o,h,l,c] = request.security("", tf, [open[lb],high[lb],low[lb],close[lb]], lookahead = barmerge.lookahead_on)


//Plotting OHLC Values ONLY for display on the price scale
plot(o, title = "Open", display = display.price_scale, color = open_color, editable = false)
plot(h, title = "High", display = display.price_scale, color = high_color, editable = false)
plot(l, title = "Low", display = display.price_scale, color = low_color, editable = false)
plot(c, title = "Close", display = display.price_scale, color = close_color, editable = false)
// This is done, because using the "trackprice" feature draws the line extending to the left AND right, we only want the line going to the right.


//Finding where the lines should start from.
origin_bar = ta.valuewhen(timeframe.change(tf),bar_index,lb) // This is for when a user uses data from a higher timeframe, this will locate the place on the chart where that bar started.
//Note: It is impossible for this value to be perfectly on the bar the candle started if the HTF requested is not perfect a multiple of the current chart's timeframe.
// ex. looking at a 3 min, requesting a 15 min IDEAL, 15/3 = 5
// ex. looking at a 3 min, requesting a 10 min NOT IDEAL, 10/3 = 3.3..., The OHLC Values will always be accurate, regardless of this factor. This is meerly visual.


//LineStyle Function to translate user inputs into proper line style format.
linestyle(_input) =>
    _input == "___"?line.style_solid:
     _input == "- - -"?line.style_dashed:
     _input == ". . ."?line.style_dotted:
     na

//Initial Creation of the Lines
var open_line = line.new(origin_bar,o, bar_index+1,o, extend = extend.right, style = linestyle(open_style), color = open_color, width = open_thickness)
var high_line = line.new(origin_bar,h, bar_index+1,h, extend = extend.right, style = linestyle(high_style), color = high_color, width = high_thickness)
var low_line = line.new(origin_bar,l, bar_index+1,l, extend = extend.right, style = linestyle(low_style), color = low_color, width = low_thickness)
var close_line = line.new(origin_bar,c, bar_index+1,c, extend = extend.right, style = linestyle(close_style), color = close_color, width = close_thickness)

//Updating the Open Line Values
line.set_xy1(open_line,origin_bar,o)
line.set_xy2(open_line,bar_index+1,o)
//Updating the High Line Values
line.set_xy1(high_line,origin_bar,h)
line.set_xy2(high_line,bar_index+1,h)
//Updating the Low Line Values
line.set_xy1(low_line,origin_bar,l)
line.set_xy2(low_line,bar_index+1,l)
//Updating the Close Line Values
line.set_xy1(close_line,origin_bar,c)
line.set_xy2(close_line,bar_index+1,c)