ATR Buy, Target, Stop + Overlay V2

Version Additions:

Target ATR % : The percentage move implied by the ATR target setting.

Stop ATR % : The percentage move implied by the ATR stop setting.

Added color options for: ATR Time Frame & ATR Value rows.

These additions we made to help estimate the move implied by the current ATR values.

// ATR Buy, Target, Stop + Overlay
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © abbadon9 [If you modify this script please acknowledge me.]

//@version=6
indicator("ATR Buy, Target, Stop + Overlay", shorttitle="ATR BTS", overlay=true)


// === INPUTS ===
buyPriceInput = input.float(title="Buy Price (enter > 0)", defval=0.0)
atrLength = input.int(title="ATR Length", defval=14)
atrTF = input.timeframe("", "ATR Timeframe Override (e.g. 'D', '1h', or blank)")
targetMult = input.float(title="Target Multiplier (ATR)", defval=1.5)
stopMult = input.float(title="Stop Multiplier (ATR)", defval=0.5)

// === Line Extension Input ===
extendBoth = input.bool(false, title="Extend Lines Both Directions", group="Line Settings")
extendOption = extendBoth ? extend.both : extend.right

// === Buy Line Inputs ===
buyLineColor = input.color(color.green, title="Buy Line Color", group="Line Settings")
buyLineStyleStr = input.string("dotted", title="Buy Line Style", options=["solid", "dashed", "dotted"], group="Line Settings")
buyLineWidth = input.int(1, title="Buy Line Width", minval=1, maxval=5, group="Line Settings")
buyLineStyle = buyLineStyleStr == "dotted" ? line.style_dotted : buyLineStyleStr == "dashed" ? line.style_dashed : line.style_solid

// === Target Line Inputs ===
targetLineColor = input.color(color.blue, title="Target Line Color", group="Line Settings")
targetLineStyleStr = input.string("dotted", title="Target Line Style", options=["solid", "dashed", "dotted"], group="Line Settings")
targetLineWidth = input.int(1, title="Target Line Width", minval=1, maxval=5, group="Line Settings")
targetLineStyle = targetLineStyleStr == "dotted" ? line.style_dotted : targetLineStyleStr == "dashed" ? line.style_dashed : line.style_solid

// === Stop Line Inputs ===
stopLineColor = input.color(color.red, title="Stop Line Color", group="Line Settings")
stopLineStyleStr = input.string("dotted", title="Stop Line Style", options=["solid", "dashed", "dotted"], group="Line Settings")
stopLineWidth = input.int(1, title="Stop Line Width", minval=1, maxval=5, group="Line Settings")
stopLineStyle = stopLineStyleStr == "dotted" ? line.style_dotted : stopLineStyleStr == "dashed" ? line.style_dashed : line.style_solid

// === Table Text Colors ===
buyTextColor    = input.color(color.green, title="Buy Text Color", group="Table Settings")
targetTextColor = input.color(color.blue, title="Target Text Color", group="Table Settings")
stopTextColor   = input.color(color.red, title="Stop Text Color", group="Table Settings")

// New text color inputs for ATR % and ATR rows
targetATRPercentTextColor = input.color(color.blue, title="Target ATR % Text Color", group="Table Settings")
stopATRPercentTextColor   = input.color(color.red, title="Stop ATR % Text Color", group="Table Settings")
atrRowTextColor           = input.color(color.gray, title="ATR Time Frame Text Color", group="Table Settings")
atrValueRowTextColor      = input.color(color.gray, title="ATR Value Text Color", group="Table Settings")

// === ATR Calculation ===
atrRaw = ta.atr(atrLength)
atr = atrTF == "" ? atrRaw : request.security(syminfo.tickerid, atrTF, atrRaw)
validBuy = buyPriceInput > 0

// === Price Levels ===
buyPrice    = validBuy ? buyPriceInput : na
targetPrice = validBuy ? buyPrice + atr * targetMult : na
stopPrice   = validBuy ? buyPrice - atr * stopMult : na

// === Line Variables ===
var line buyLine = na
var line targetLine = na
var line stopLine = na

if barstate.islast
    if not na(buyLine)
        line.delete(buyLine)
    if not na(targetLine)
        line.delete(targetLine)
    if not na(stopLine)
        line.delete(stopLine)

    if validBuy
        buyLine   := line.new(bar_index, buyPrice, bar_index + 1, buyPrice, color=buyLineColor, width=buyLineWidth, style=buyLineStyle)
        targetLine:= line.new(bar_index, targetPrice, bar_index + 1, targetPrice, color=targetLineColor, width=targetLineWidth, style=targetLineStyle)
        stopLine  := line.new(bar_index, stopPrice, bar_index + 1, stopPrice, color=stopLineColor, width=stopLineWidth, style=stopLineStyle)

        line.set_extend(buyLine, extendOption)
        line.set_extend(targetLine, extendOption)
        line.set_extend(stopLine, extendOption)

// === Table Settings Inputs ===
bg_col = input.color(color.new(color.black, 100), title="Background Color", group="Table Settings")
showTableHeader             = input.bool(true,  title="Add Empty Top Spacer Row", group="Table Settings")
tablePositionOption         = input.string("bottom_right", title="Table Position", options=["top_right","top_left","bottom_right","bottom_left"], group="Table Settings")

// === Table Row Toggles ===
showBuyRow             = input.bool(true, title="Show Buy Row", group="Table Settings")
showTargetRow          = input.bool(true, title="Show Target Row", group="Table Settings")
showTargetATRPercentRow= input.bool(true, title="Show Target ATR % Row", group="Table Settings")
showStopRow            = input.bool(true, title="Show Stop Row", group="Table Settings")
showStopATRPercentRow  = input.bool(true, title="Show Stop ATR % Row", group="Table Settings")
showATRRow             = input.bool(true, title="Show ATR Time Frame Row", group="Table Settings")
showATRValueRow        = input.bool(true, title="Show ATR Value Row", group="Table Settings")

// Map string to position constant
tablePos = tablePositionOption == "top_right" ? position.top_right :
           tablePositionOption == "top_left" ? position.top_left :
           tablePositionOption == "bottom_right" ? position.bottom_right :
           position.bottom_left

// Determine visible rows
visibleRowCount = (showBuyRow ? 1 : 0) + (showTargetRow ? 1 : 0) + (showTargetATRPercentRow ? 1 : 0) + (showStopRow ? 1 : 0) + (showStopATRPercentRow ? 1 : 0) + (showATRRow ? 1 : 0) + (showATRValueRow ? 1 : 0)
rowsCount        = visibleRowCount + (showTableHeader ? 1 : 0)

// === Table ===
var table infoTable = table.new(tablePos, 2, rowsCount, border_width=1)

if validBuy
    rowOffset = showTableHeader ? 1 : 0
    if showTableHeader
        table.cell(infoTable, 0, 0, "", bgcolor=bg_col)
        table.cell(infoTable, 1, 0, "", bgcolor=bg_col)
    row = rowOffset

    if showBuyRow
        table.cell(infoTable, 0, row, "Buy Price", text_color=buyTextColor)
        table.cell(infoTable, 1, row, str.tostring(buyPrice, "#.##"), text_color=buyTextColor)
        row += 1

    if showTargetRow
        table.cell(infoTable, 0, row, "Target (" + str.tostring(targetMult) + "x ATR)", text_color=targetTextColor)
        table.cell(infoTable, 1, row, str.tostring(targetPrice, "#.##"), text_color=targetTextColor)
        row += 1

    if showTargetATRPercentRow
        table.cell(infoTable, 0, row, "Target ATR %", text_color=targetATRPercentTextColor)
        table.cell(infoTable, 1, row, str.tostring((atr * targetMult / buyPrice) * 100, "#.##") + "%", text_color=targetATRPercentTextColor)
        row += 1

    if showStopRow
        table.cell(infoTable, 0, row, "Stop (" + str.tostring(stopMult) + "x ATR)", text_color=stopTextColor)
        table.cell(infoTable, 1, row, str.tostring(stopPrice, "#.##"), text_color=stopTextColor)
        row += 1

    if showStopATRPercentRow
        table.cell(infoTable, 0, row, "Stop ATR %", text_color=stopATRPercentTextColor)
        table.cell(infoTable, 1, row, str.tostring((atr * stopMult / buyPrice) * 100, "#.##") + "%", text_color=stopATRPercentTextColor)
        row += 1

    if showATRRow
        table.cell(infoTable, 0, row, "ATR Time Frame", text_color=atrRowTextColor)
        table.cell(infoTable, 1, row, atrTF == "" ? "Chart" : atrTF, text_color=atrRowTextColor)
        row += 1

    if showATRValueRow
        table.cell(infoTable, 0, row, "ATR Value", text_color=atrValueRowTextColor)
        table.cell(infoTable, 1, row, str.tostring(atr, "#.###"), text_color=atrValueRowTextColor)
else
    table.clear(infoTable, 0, 0)