Free reference · copy, paste, keep

    Pine Script snippet library

    16 working Pine Script v5 blocks for the plumbing every custom script needs — non-repainting higher-timeframe data, session levels, alerts, webhook JSON, on-chart tables and debugging. Every snippet compiles on its own, and none of them contain entry logic.

    Short answer

    Pine Script is TradingView's scripting language. Every script starts with //@version=5 followed by an indicator() or strategy() declaration. Paste any block below into the Pine Editor at the bottom of a TradingView chart and click Add to chart.

    • Avoid repainting: gate conditions with barstate.isconfirmed.
    • Higher-timeframe data: request.security with lookahead_off and a [1] offset.
    • Alerts: pass alert.freq_once_per_bar_close to alert().
    • Webhooks: build a valid JSON string and send it as the alert message.
    • Debugging: plotchar marks every bar where a condition is true.

    Showing 16 of 16 snippets.

    Starting points

    Indicator skeleton

    The minimum valid indicator: version, declaration, one input, one plot.

    Pine Script v5

    //@version=5 indicator("My Indicator", overlay = true) length = input.int(20, "Length", minval = 1) ma = ta.sma(close, length) plot(ma, "MA", color = color.new(color.aqua, 0), linewidth = 2)

    Note: overlay=true draws on the price chart. Set it to false for a separate pane.

    Strategy skeleton with a placeholder condition

    A strategy shell with percent-of-equity sizing where you fill in your own entry rule.

    Pine Script v5

    //@version=5 strategy("My Strategy", overlay = true, default_qty_type = strategy.percent_of_equity, default_qty_value = 10, process_orders_on_close = true) // Replace this with your own rule: myEntryCondition = close > open if myEntryCondition strategy.entry("Long", strategy.long)

    Note: Replace the myEntryCondition line with your own logic — everything else is wired up.

    Grouped, tidy inputs

    Inputs organised into labelled groups with inline pairing.

    Pine Script v5

    //@version=5 indicator("Grouped Inputs", overlay = true) gLevels = "Levels" gStyle = "Style" levelPrice = input.price(0, "Watch price", group = gLevels) showLine = input.bool(true, "Show line", group = gLevels) lineColor = input.color(color.orange, "Line colour", group = gStyle, inline = "style") lineWidth = input.int(2, "Width", minval = 1, maxval = 4, group = gStyle, inline = "style") plot(showLine ? levelPrice : na, "Level", color = lineColor, linewidth = lineWidth)

    Note: group and inline keep the settings panel readable once you pass ~6 inputs.

    Non-repainting higher-timeframe value

    Requests a higher-timeframe value without it changing after the fact.

    Pine Script v5

    //@version=5 indicator("HTF Value (non-repainting)", overlay = true) htf = input.timeframe("60", "Higher timeframe") length = input.int(50, "EMA length") htfEma = request.security(syminfo.tickerid, htf, ta.ema(close, length)[1], lookahead = barmerge.lookahead_off) plot(htfEma, "HTF EMA", color = color.yellow, linewidth = 2)

    Note: lookahead_off with a [1] offset is the standard non-repainting pattern.

    Levels & sessions

    Previous day high, low and close

    Daily reference levels plotted on any intraday chart.

    Pine Script v5

    //@version=5 indicator("Previous Day Levels", overlay = true) pdh = request.security(syminfo.tickerid, "D", high[1], lookahead = barmerge.lookahead_on) pdl = request.security(syminfo.tickerid, "D", low[1], lookahead = barmerge.lookahead_on) pdc = request.security(syminfo.tickerid, "D", close[1], lookahead = barmerge.lookahead_on) plot(pdh, "PDH", color.red, style = plot.style_stepline) plot(pdl, "PDL", color.green, style = plot.style_stepline) plot(pdc, "PDC", color.gray, style = plot.style_stepline)

    Note: The [1] index takes the completed day, so the levels never move intraday.

    Session opening range

    Tracks the high and low of a chosen session window.

    Pine Script v5

    //@version=5 indicator("Opening Range", overlay = true) sess = input.session("0930-1000", "Opening range session") tz = input.string("America/New_York", "Timezone") inSess = not na(time(timeframe.period, sess, tz)) var float orHigh = na var float orLow = na if inSess and not inSess[1] orHigh := high orLow := low else if inSess orHigh := math.max(orHigh, high) orLow := math.min(orLow, low) plot(orHigh, "OR High", color.aqua, style = plot.style_linebr) plot(orLow, "OR Low", color.fuchsia, style = plot.style_linebr)

    Note: Change the session string to match your market and exchange timezone.

    Session background shading

    Tints the chart background during a chosen session so the window is obvious at a glance.

    Pine Script v5

    //@version=5 indicator("Session Shading", overlay = true) sess = input.session("0930-1600", "Session to highlight") tz = input.string("America/New_York", "Timezone") inSess = not na(time(timeframe.period, sess, tz)) bgcolor(inSess ? color.new(color.blue, 90) : na)

    Note: Keep the transparency above 85 or the candles get hard to read.

    Horizontal level with an alert

    Plots a price level you type in and alerts when price crosses it.

    Pine Script v5

    //@version=5 indicator("Level Alert", overlay = true) level = input.price(0, "Watch price") plot(level, "Level", color.orange, linewidth = 2, style = plot.style_linebr) crossedUp = ta.crossover(close, level) crossedDown = ta.crossunder(close, level) alertcondition(crossedUp, "Crossed above", "{{ticker}} crossed above your level at {{close}}") alertcondition(crossedDown, "Crossed below", "{{ticker}} crossed below your level at {{close}}")

    Note: This is condition-agnostic — the alert fires on a simple price cross of your level.

    Tables & drawings

    On-chart info table

    A corner table showing live values without cluttering the chart.

    Pine Script v5

    //@version=5 indicator("Info Table", overlay = true) atr = ta.atr(14) rsi = ta.rsi(close, 14) var table t = table.new(position.top_right, 2, 3, border_width = 1, frame_color = color.new(color.gray, 60)) if barstate.islast table.cell(t, 0, 0, "Metric", text_color = color.gray, text_size = size.small) table.cell(t, 1, 0, "Value", text_color = color.gray, text_size = size.small) table.cell(t, 0, 1, "ATR(14)", text_color = color.white, text_size = size.small) table.cell(t, 1, 1, str.tostring(atr, "#.####"), text_color = color.white, text_size = size.small) table.cell(t, 0, 2, "RSI(14)", text_color = color.white, text_size = size.small) table.cell(t, 1, 2, str.tostring(rsi, "#.##"), text_color = color.white, text_size = size.small)

    Note: Build the table once with var, then update cells on the last bar only.

    Multi-symbol watchlist table

    Quotes up to five other tickers in a corner table while you chart something else.

    Pine Script v5

    //@version=5 indicator("Watchlist Table", overlay = true) s1 = input.symbol("SPY") s2 = input.symbol("QQQ") s3 = input.symbol("DIA") c1 = request.security(s1, timeframe.period, close) c2 = request.security(s2, timeframe.period, close) c3 = request.security(s3, timeframe.period, close) var table t = table.new(position.top_right, 2, 4, border_width = 1) if barstate.islast table.cell(t, 0, 0, "Symbol", text_color = color.gray, text_size = size.small) table.cell(t, 1, 0, "Last", text_color = color.gray, text_size = size.small) table.cell(t, 0, 1, s1, text_color = color.white, text_size = size.small) table.cell(t, 1, 1, str.tostring(c1, "#.##"), text_color = color.white, text_size = size.small) table.cell(t, 0, 2, s2, text_color = color.white, text_size = size.small) table.cell(t, 1, 2, str.tostring(c2, "#.##"), text_color = color.white, text_size = size.small) table.cell(t, 0, 3, s3, text_color = color.white, text_size = size.small) table.cell(t, 1, 3, str.tostring(c3, "#.##"), text_color = color.white, text_size = size.small)

    Note: request.security calls are limited per script, so keep the list short.

    Custom bar colouring

    Recolours candles by any condition you choose, without drawing extra lines.

    Pine Script v5

    //@version=5 indicator("Custom Bar Color", overlay = true) // Replace this with any condition you like: highlight = close > ta.sma(close, 50) barcolor(highlight ? color.new(color.teal, 0) : na)

    Note: Turn off the symbol's own body and wick colours in chart settings so yours are visible.

    Filled area between two plots

    Shades the space between any two plots — bands, channels or averages.

    Pine Script v5

    //@version=5 indicator("Filled Channel", overlay = true) len = input.int(20, "Length") mult = input.float(2.0, "Width", step = 0.1) basis = ta.sma(close, len) offset = ta.stdev(close, len) * mult pUp = plot(basis + offset, "Upper", color = color.new(color.teal, 0)) pLow = plot(basis - offset, "Lower", color = color.new(color.maroon, 0)) fill(pUp, pLow, color = color.new(color.blue, 92))

    Note: fill() needs two plot IDs, so assign your plots to variables first.

    Labels that clean up after themselves

    Keeps only the most recent N labels so the chart stays readable.

    Pine Script v5

    //@version=5 indicator("Rolling Labels", overlay = true, max_labels_count = 500) keep = input.int(20, "Labels to keep", minval = 1) mark = close > open and close[1] <= open[1] // any condition you want to mark var label[] store = array.new_label() if mark l = label.new(bar_index, low, "•", yloc = yloc.belowbar, style = label.style_label_up, color = color.new(color.green, 20), textcolor = color.white, size = size.tiny) array.push(store, l) if array.size(store) > keep label.delete(array.shift(store))

    Note: TradingView caps drawings, so old labels disappear silently without this.

    Debugging

    See any condition on the chart with plotchar

    Marks every bar where your boolean is true — the fastest way to sanity-check logic.

    Pine Script v5

    //@version=5 indicator("Condition Debugger", overlay = true) // Put the condition you are testing here: myCondition = close > open and volume > ta.sma(volume, 20) plotchar(myCondition, "Condition true", "•", location.belowbar, color = color.new(color.yellow, 0), size = size.tiny)

    Note: If the dots do not land where you expect, the condition is wrong, not the drawing.

    Print values into the Data Window

    Exposes intermediate values so you can hover any bar and inspect them.

    Pine Script v5

    //@version=5 indicator("Value Inspector", overlay = false) body = close - open range = high - low ratio = range != 0 ? body / range : 0 plot(body, "Body", display = display.data_window) plot(range, "Range", display = display.data_window) plot(ratio, "Body / Range", display = display.data_window)

    Note: display.data_window keeps the value out of the chart but visible on hover.

    Webhook JSON payload template

    A valid JSON alert body most webhook receivers can parse — plug in your own trigger.

    Pine Script v5

    //@version=5 indicator("Webhook JSON", overlay = true) // Replace this with your own trigger condition: trigger = ta.cross(close, input.price(0, "Trigger price")) if trigger msg = '{"ticker":"' + syminfo.ticker + '",' + '"price":' + str.tostring(close, format.mintick) + ',' + '"timeframe":"' + timeframe.period + '",' + '"time":"' + str.format_time(time, "yyyy-MM-dd'T'HH:mm:ssZ", "UTC") + '"}' alert(msg, alert.freq_once_per_bar_close)

    Note: Keep it valid JSON — a trailing comma or smart quote breaks the receiver.

    How to run any of these

    1. 1.Open any chart on TradingView and click Pine Editor along the bottom bar.
    2. 2.Select all the placeholder code in the editor and delete it.
    3. 3.Paste a snippet from this page, then click Save and give it a name.
    4. 4.Click Add to chart. Compile errors appear in the console below the editor.
    5. 5.Open the settings gear on the indicator to change any of its inputs.

    For the full list of alert variables and a webhook payload builder, see the TradingView alert placeholder reference. If an alert is not firing at all, the alerts troubleshooting guide covers the usual causes.

    Cite or reuse this page

    This reference is free to quote, screenshot, teach from or republish in part, for any purpose including commercial, as long as you credit the source with a working link.

    Citation

    SimpleAlgo. (2026). Pine Script Snippet Library. Retrieved from https://simplealgo.io/pine-script-snippets

    Link HTML

    <a href="https://simplealgo.io/pine-script-snippets">Pine Script Snippet Library — SimpleAlgo</a>

    Embed this table

    <iframe src="https://simplealgo.io/pine-script-snippets" width="100%" height="720" style="border:1px solid #222;border-radius:10px" title="Pine Script Snippet Library — SimpleAlgo"></iframe> <p><a href="https://simplealgo.io/pine-script-snippets">Pine Script Snippet Library</a> by SimpleAlgo</p>

    Or skip the coding entirely

    These snippets handle the scaffolding — sessions, levels, tables, debugging. The hard part is the entry logic, and that is what SimpleAlgo V5 ships: bar-close signals, volatility-based stops and targets, structure markup and ready-made alerts, already assembled on your TradingView chart. $24.95 per week or $300 per year, with a 7-day money-back guarantee.

    Frequently asked questions

    Are these Pine Script snippets free to use?
    Yes. Copy them into your own scripts, modify them, and publish the result. A credit link back to SimpleAlgo is appreciated but not required.
    What version of Pine Script is this?
    Pine Script v5, declared with //@version=5 at the top of every snippet. Most will not compile under v4 without changes, because function namespaces such as ta. and request. were introduced in v5.
    Do these snippets generate buy or sell signals?
    No. This library covers plumbing — sessions, levels, tables, drawings, debugging and alert formatting — not entry logic. Where a trigger is needed, the snippet uses an obvious placeholder for you to replace with your own idea.
    How do I stop my indicator from repainting?
    Two habits cover most cases: evaluate conditions on confirmed bars using barstate.isconfirmed, and request higher-timeframe data with lookahead=barmerge.lookahead_off plus a [1] offset. The non-repainting higher-timeframe snippet on this page shows the pattern.
    Why does my alert fire multiple times per bar?
    The default alert frequency evaluates intrabar. Pass alert.freq_once_per_bar_close to alert(), and set the alert itself to 'Once per bar close' in the TradingView dialog.
    Why do my labels disappear from older bars?
    TradingView limits how many drawing objects a script can keep. Raise the ceiling with max_labels_count in the indicator declaration, and delete old labels yourself — the rolling labels snippet on this page does both.

    Alert variables, TradingView tutorials and how our own signals are built.

    Educational reference only. Nothing here is financial advice, and trading carries a substantial risk of loss. SimpleAlgo is not affiliated with, endorsed by, or sponsored by TradingView. TradingView and Pine Script are trademarks of TradingView, Inc.