Change the border size of a box in TradingView Pine Script
TL;DR
Adjust box outlines withbox.set_border_width()to direct attention to the freshest price zones.
At a Glance
Section titled “At a Glance”| Difficulty | Beginner |
| Time to implement | 5-10 min |
| Category | Visual Effects |
Quick Actions
Section titled “Quick Actions”Quick Start
Section titled “Quick Start”//@version=6indicator("Box border quick start", overlay=true)
var box hiZone = na
if ta.crossover(close, ta.sma(close, 20)) hiZone := box.new( left = bar_index, top = high * 1.005, right = bar_index + 6, bottom = low * 0.995, bgcolor = color.new(color.orange, 85) )
if not na(hiZone) box.set_border_width(hiZone, close > ta.sma(close, 20) ? 4 : 1)box.set_border_width() with the same identifier returned from box.new(). Updating in place means the chart never flashes or repaints the region.
Why It Matters
Section titled “Why It Matters”Pine Script boxes are ideal for highlighting support, resistance, or signal zones, but static outlines fail to show which region is fresh. Dynamic borders let you emphasise active setups, soften older ones, and recycle drawings without recreating them. The result is a cleaner chart that still tells a story about recency and importance.
What You’ll Learn
Section titled “What You’ll Learn”- Persist a box identifier across bars for later edits
- Change border widths as conditions evolve
- Sync outlines with colour and transparency cues
- Retire or hide outdated highlights cleanly
Quick Reference
Section titled “Quick Reference”| Call | Purpose |
|---|---|
box.new() | Creates a drawing and returns the identifier you must keep to modify it later. |
box.set_border_width() | Changes outline thickness without recreating the box. |
box.set_border_color() | Updates the outline colour to match the current emphasis. |
box.set_bgcolor() | Adjusts fill transparency alongside border tweaks. |
box.delete() | Removes the drawing when the setup is invalidated. |
Implementation Blueprint
Section titled “Implementation Blueprint”-
Create a box handle that persists
Store the identifier frombox.new()in avarso it survives new bars. Without it, nothing can be updated later.var box sessionBox = naif ta.change(time("D"))sessionBox := box.new(left = bar_index,top = high,right = bar_index + 1,bottom = low,bgcolor = color.new(color.blue, 90)) -
Emphasise the active zone
Drive the outline width from your signal logic. A wide border highlights the current opportunity, while a narrow one keeps context.if not na(sessionBox)bool isHot = close > ta.sma(close, 50)box.set_border_width(sessionBox, isHot ? 4 : 1)box.set_border_color(sessionBox, isHot ? color.new(color.blue, 0) : color.new(color.gray, 40)) -
Fade or clear stale regions
Hide the outline when the setup invalidates, or delete the box entirely when the structure no longer matters.if not na(sessionBox) and ta.crossunder(close, ta.sma(close, 50))box.set_border_width(sessionBox, 0) // keep the fill but hide the outlineif not na(sessionBox) and barstate.islastconfirmedhistorybox.delete(sessionBox) // optional clean-up to prevent piling boxes
Example Playbook
Section titled “Example Playbook”//@version=5indicator("Dynamic zone outline", overlay=true)
length = input.int(34, "MA length")lookaheadBars = input.int(12, "Box width (bars)")
ma = ta.sma(close, length)trigger = ta.crossover(close, ma) or ta.crossunder(close, ma)
var box signalBox = na
if trigger color accent = ta.crossover(close, ma) ? color.green : color.red signalBox := box.new( left = bar_index, top = high * 1.003, right = bar_index + lookaheadBars, bottom = low * 0.997, bgcolor = color.new(accent, 88), border_color = accent, border_width = 4 )
if not na(signalBox) age = bar_index - box.get_left(signalBox) fadingWidth = math.max(1, 4 - math.floor(age / 3)) box.set_border_width(signalBox, fadingWidth) box.set_border_color(signalBox, color.new(box.get_border_color(signalBox), age > lookaheadBars ? 60 : 0))
plot(ma, "Signal MA", color=color.gray)- New signals get a crisp four-pixel outline and bright colour.
- Each bar reduces the width, so attention naturally shifts to newer setups.
- Once the age threshold is hit, colour transparency increases to avoid clutter.
Pro Tips & Pitfalls
Section titled “Pro Tips & Pitfalls”- Persist box identifiers with
varor collections; local variables reset every bar. box.set_border_width()expects integers—wrap dynamic calculations withmath.round()if needed.- A width of
0hides the outline but keeps the fill. Delete the box if you need it gone. - Pair width changes with colour or transparency updates so emphasis feels deliberate.
Troubleshooting & FAQ
Section titled “Troubleshooting & FAQ”Why does my box vanish after setting the width to zero?
Section titled “Why does my box vanish after setting the width to zero?”Setting width to 0 hides the outline. If you also set the fill to a fully transparent colour, nothing is visible. Either keep a subtle fill or recreate the box when the setup returns.
Can I style each edge of the box differently?
Section titled “Can I style each edge of the box differently?”No. Pine Script boxes apply border settings to all four sides simultaneously. To emulate per-edge styling, overlay multiple boxes with different coordinates and widths.
Key Takeaways
Section titled “Key Takeaways”- Store the
box.new()identifier so you can adjust it across future bars. - Use
box.set_border_width()to highlight or de-emphasise zones without redrawing. - Combine width, colour, and transparency changes for expressive visual cues.
- Clean up stale boxes with width
0orbox.delete()to keep charts readable.
Keep Going
Section titled “Keep Going”- Open AI Editor to apply the pattern with guided assistance
- Browse Strategy Examples for ready-to-run templates
- Connect to Live Trading when you are ready to automate
Adapted from tradingcode.net, optimised for Algo Trade Analytics users.