OPEN-SOURCE SCRIPT
Ohm Horizontal line

//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)
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)
Skrip open-source
Dengan semangat TradingView yang sesungguhnya, penulis skrip ini telah menjadikannya sumber terbuka, sehingga para trader dapat meninjau dan memverifikasi fungsinya. Hormat untuk penulisnya! Meskipun anda dapat menggunakannya secara gratis, ingatlah bahwa penerbitan ulang kode tersebut tunduk pada Tata Tertib kami.
Pernyataan Penyangkalan
Informasi dan publikasi tidak dimaksudkan untuk menjadi, dan bukan merupakan saran keuangan, investasi, perdagangan, atau rekomendasi lainnya yang diberikan atau didukung oleh TradingView. Baca selengkapnya di Persyaratan Penggunaan.
Skrip open-source
Dengan semangat TradingView yang sesungguhnya, penulis skrip ini telah menjadikannya sumber terbuka, sehingga para trader dapat meninjau dan memverifikasi fungsinya. Hormat untuk penulisnya! Meskipun anda dapat menggunakannya secara gratis, ingatlah bahwa penerbitan ulang kode tersebut tunduk pada Tata Tertib kami.
Pernyataan Penyangkalan
Informasi dan publikasi tidak dimaksudkan untuk menjadi, dan bukan merupakan saran keuangan, investasi, perdagangan, atau rekomendasi lainnya yang diberikan atau didukung oleh TradingView. Baca selengkapnya di Persyaratan Penggunaan.