ATR Buy, Target, Stop + Overlay

This tool is to assist traders with precise trade planning using the Average True Range (ATR) as a volatility-based reference.

This script plots buy, target, and stop-loss levels on the chart based on a user-defined buy price and ATR-based multipliers, allowing for objective and adaptive trade management.

*NOTE* In order for the indicator to initiate plotted lines and table values a non-zero number must be entered into the settings.

What It Does:

Buy Price Input: Users enter a manual buy price (e.g., an executed or planned trade entry).

ATR-Based Target and Stop: The script calculates:

Target Price = Buy + (ATR × Target Multiplier)

Stop Price = Buy − (ATR × Stop Multiplier)

Customizable Timeframe: Optionally override the ATR timeframe (e.g., use daily ATR on a 1-hour chart).

Visual Overlay: Lines are drawn directly on the price chart for the Buy, Target, and Stop levels.

Interactive Table: A table is displayed with relevant levels and ATR info.

Customization Options:

Line Settings:

Adjust color, style (solid/dashed/dotted), and width for Buy, Target, and Stop lines.

Choose whether to extend lines rightward only or in both directions.

Table Settings:

Choose position (top/bottom, left/right).

Toggle individual rows for Buy, Target, Stop, ATR Timeframe, and ATR Value.

Customize text color and background transparency.

How to Use It for Trading:

Plan Your Trade: Enter your intended buy price when planning a trade.

Assess Risk/Reward: The script immediately visualizes the potential stop-loss and target level, helping assess R:R ratios.

Adapt to Volatility: Use ATR-based levels to scale stop and target dynamically depending on current market volatility.

Higher Timeframe ATR: Select a different timeframe for the ATR calculation to smooth noise on lower timeframe charts.

On-the-Chart Reference: Visually track trade zones directly on the price chart—ideal for live trading or strategy backtesting.

Ideal For:

Swing traders and intraday traders

Risk management and trade planning

Traders using ATR-based exits or scaling

Visualizing asymmetric risk/reward setups

How I Use This:

After entering a trade, adding an entry price will plot desired ATR target and stop level for visualization.

Adjusting ATR multiplier values assists in evaluating and planning trades.

Visualization assists in comparing ATR multiples to recent support and resistance levels.

// 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")

// === 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")
showStopRow = input.bool(true, title="Show Stop 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  // default

// Determine visible rows
visibleRowCount = (showBuyRow ? 1 : 0) + (showTargetRow ? 1 : 0) + (showStopRow ? 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 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 showATRRow
        table.cell(infoTable, 0, row, "ATR Time Frame", text_color=color.gray)
        table.cell(infoTable, 1, row, atrTF == "" ? "Chart" : atrTF, text_color=color.gray)
        row += 1

    if showATRValueRow  // ✅ NEW ROW
        table.cell(infoTable, 0, row, "ATR Value", text_color=color.gray)
        table.cell(infoTable, 1, row, str.tostring(atr, "#.###"), text_color=color.gray)

else
    table.clear(infoTable, 0, 0)