OPEN-SOURCE SCRIPT

Ohm Horizontal line

56
//version=5
indicator("Ohm Horizontal line", overlay=true)

// Input parameters
atrPeriod = input.int(14, "ATR Period", minval=1)
atrMultiplier = input.float(1.0, "ATR Multiplier", step=0.1)
numLevels = input.int(10, "Number of Levels (each side)", minval=1)
lineWidth = input.int(1, "Line Width", minval=1, maxval=4)
labelOffset = input.int(20, "Label Offset", minval=0)

// Calculate daily ATR
dailyAtr = request.security(syminfo.tickerid, "D", ta.atr(atrPeriod))

// Function to get rounded price based on ATR
getRoundedPrice(price, atrValue) =>
math.round(price / (atrValue * atrMultiplier)) * (atrValue * atrMultiplier)

// Calculate center price (current close rounded to nearest ATR multiple)
centerPrice = getRoundedPrice(close, dailyAtr)

// Create arrays for price levels
var float[] levels = array.new_float(2 * numLevels + 1)
var float[] midLevels = array.new_float(2 * numLevels)

// Update price levels
updateLevels() =>
array.set(levels, numLevels, centerPrice)
for i = 1 to numLevels
upperLevel = centerPrice + i * dailyAtr * atrMultiplier
lowerLevel = centerPrice - i * dailyAtr * atrMultiplier
array.set(levels, numLevels + i, upperLevel)
array.set(levels, numLevels - i, lowerLevel)

// Calculate mid levels
if i > 1
upperMid = (array.get(levels, numLevels + i) + array.get(levels, numLevels + i - 1)) / 2
lowerMid = (array.get(levels, numLevels - i) + array.get(levels, numLevels - i + 1)) / 2
array.set(midLevels, numLevels + i - 2, upperMid)
array.set(midLevels, numLevels - i + 1, lowerMid)

// Update levels on every bar
updateLevels()

// Plot horizontal lines and price labels
var line[] horizontalLines = array.new_line(2 * numLevels + 1)
var line[] midLines = array.new_line(2 * numLevels)
var label[] priceLabels = array.new_label(2 * numLevels + 1)

// Function to draw or update a line
drawLine(lineArray, index, y, color, width, style) =>
if na(array.get(lineArray, index))
array.set(lineArray, index, line.new(bar_index, y, bar_index + 1, y, color=color, width=width, style=style, extend=extend.both))
else
line.set_xy1(array.get(lineArray, index), bar_index, y)
line.set_xy2(array.get(lineArray, index), bar_index + 1, y)
line.set_color(array.get(lineArray, index), color)
line.set_width(array.get(lineArray, index), width)
line.set_style(array.get(lineArray, index), style)

// Draw main levels
for i = 0 to 2 * numLevels
level = array.get(levels, i)
lineColor = i == numLevels ? color.yellow : (i > numLevels ? color.green : color.red)
drawLine(horizontalLines, i, level, lineColor, lineWidth, line.style_solid)

if na(array.get(priceLabels, i))
array.set(priceLabels, i, label.new(bar_index + labelOffset, level, str.tostring(level, format.mintick), color=color.new(color.black, 100), textcolor=lineColor, style=label.style_none, size=size.small))
else
label.set_xy(array.get(priceLabels, i), bar_index + labelOffset, level)
label.set_text(array.get(priceLabels, i), str.tostring(level, format.mintick))
label.set_textcolor(array.get(priceLabels, i), lineColor)

// Draw mid levels (without labels)
for i = 0 to 2 * numLevels - 1
midLevel = array.get(midLevels, i)
lineColor = i >= numLevels ? color.new(color.green, 50) : color.new(color.red, 50)
drawLine(midLines, i, midLevel, lineColor, 1, line.style_dashed)

// Display current ATR value
var label atrLabel = na
label.delete(atrLabel)
atrLabel := label.new(bar_index[labelOffset], high, text="ATR: " + str.tostring(dailyAtr, "#.##"), color=color.new(color.blue, 0), textcolor=color.white, size=size.small)

Disclaimer

The information and publications are not meant to be, and do not constitute, financial, investment, trading, or other types of advice or recommendations supplied or endorsed by TradingView. Read more in the Terms of Use.