Home Blog Pine Script Beginners Guide
Tutorial

TradingView Pine Script for Beginners

Build a custom momentum indicator from scratch — no prior coding required. Takes 20 minutes.

Updated April 2026 · Pine Script v5

Pine Script is TradingView's built-in programming language for custom indicators and strategies. It looks intimidating if you've never written code. It isn't. The syntax is minimal, TradingView runs it for you, and you can find errors immediately by looking at the chart.

This guide builds a real, usable indicator: a Momentum Divergence Scanner that highlights when price makes a new high but RSI doesn't — a classic setup for spotting exhaustion in trends. By the end, you'll understand Pine Script well enough to modify existing community scripts and write simple indicators from scratch.

What You Need
  • A TradingView account (free tier works)
  • A chart open on any symbol
  • No programming experience required

Step 1: Open the Pine Script Editor

From any TradingView chart, click the Pine Editor button at the bottom of the screen (or press Alt+P). A code editor opens below your chart. You'll see a default script that looks like this:

// Default script
//@version=5
indicator("My Script", overlay=true)
plot(close)

Those 3 lines are a complete Pine Script indicator. The //@version=5 declaration tells TradingView to use Pine Script v5. The indicator() function names the script. The plot() function draws a line.

Step 2: Understand the Core Concepts

Pine Script has three things you need to understand before writing anything useful:

1. Built-in series

open, high, low, close, volume are automatically available for every candle on the chart. bar_index gives you the position of the current candle. These are "series" — arrays of values, one per candle, where the rightmost value is the current candle.

2. Functions

TradingView includes built-in functions for every common calculation: ta.rsi(), ta.sma(), ta.ema(), ta.macd(). You call them with the source series and the period: ta.rsi(close, 14).

3. Historical reference with []

close[1] is the previous candle's close. close[5] is 5 candles ago. This is how you compare current values to past values.

Step 3: Build the Momentum Divergence Indicator

Here's the complete script. Copy it into the Pine Editor and click Add to chart:

//@version=5
indicator("Momentum Divergence Scanner", overlay=true, max_labels_count=500)
 
// — Inputs —
rsiLen = input.int(14, "RSI Length", minval=2)
lookback = input.int(5, "Lookback Candles", minval=2)
 
// — Calculations —
rsi = ta.rsi(close, rsiLen)
 
// Bearish divergence: price makes higher high, RSI makes lower high
priceHigher = high > ta.highest(high[1], lookback)
rsiLower = rsi < ta.highest(rsi[1], lookback)
bearDiv = priceHigher and rsiLower
 
// Bullish divergence: price makes lower low, RSI makes higher low
priceLower = low < ta.lowest(low[1], lookback)
rsiHigher = rsi > ta.lowest(rsi[1], lookback)
bullDiv = priceLower and rsiHigher
 
// — Plot labels on the chart —
if bearDiv
    label.new(bar_index, high, "⚠ Bear Div",
        style=label.style_label_down,
        color=color.new(color.red, 20),
        textcolor=color.white, size=size.small)
 
if bullDiv
    label.new(bar_index, low, "✓ Bull Div",
        style=label.style_label_up,
        color=color.new(color.green, 20),
        textcolor=color.white, size=size.small)
 
// Background highlight on divergence candles
bgcolor(bearDiv ? color.new(color.red, 88) : na)
bgcolor(bullDiv ? color.new(color.green, 88) : na)

Step 4: How It Works — Line by Line

rsiLen = input.int(14, "RSI Length")

input.int() creates a number input that appears in the indicator settings panel. The first argument is the default value (14). Users can change it without editing the code.

priceHigher = high > ta.highest(high[1], lookback)

ta.highest(high[1], lookback) finds the highest value in the high series, starting from 1 candle ago and going back lookback candles. If today's high is greater than the highest high of the past 5 candles (excluding today), that's a new high — priceHigher is true.

bearDiv = priceHigher and rsiLower

Both conditions must be true simultaneously. Pine Script's and keyword works exactly like English: price is making a new high AND RSI is not confirming it.

bgcolor(bearDiv ? color.new(color.red, 88) : na)

The ternary operator condition ? value_if_true : value_if_false is Pine Script's shorthand for if/else in a single line. If bearDiv is true, paint the background red at 88% transparency. If not, na (no value) means no background color.

Step 5: Common Modifications

Once you understand the base script, here are the most useful modifications:

Add an alert condition
alertcondition(bearDiv, "Bearish Divergence", "Bear div on {{ticker}}")
alertcondition(bullDiv, "Bullish Divergence", "Bull div on {{ticker}}")

Add these lines to the script. Then create an alert from the chart (right-click → Add Alert) and select your script from the condition dropdown. TradingView will notify you when a divergence fires. Note: you need at least the Essential plan to set more than 1 alert.

Use MACD instead of RSI
// Replace the RSI lines with:
[macdLine, signalLine, hist] = ta.macd(close, 12, 26, 9)
momentumSource = macdLine // use macdLine instead of rsi

Swap rsi for macdLine in the divergence conditions. The divergence logic is identical — you're just checking whether the momentum oscillator confirms the price move.

Filter for overbought/oversold
// Only flag bearish divergence when RSI is overbought
bearDiv = priceHigher and rsiLower and rsi > 65
bullDiv = priceLower and rsiHigher and rsi < 35

Adding an RSI level filter reduces false signals. A bearish divergence at RSI 45 is less meaningful than one at RSI 72. This one-line change reduces the signal count and improves signal quality.

What You Can't Do on Free (and How to Unlock It)

The Pine Script editor itself is available on the free plan. The limitations that affect Pine Script users specifically:

For most users getting started with Pine Script, the Essential plan at $14.95/mo removes the limits that actually matter during active trading. The indicator limit (3 → 5) and alert limit (1 → 20) are the two that bind first.

Next Steps in Pine Script

After you've run this indicator and made a few modifications, these are the skills worth adding in order:

  1. strategy() vs indicator() — The strategy() function adds backtesting capability. Use strategy.entry() and strategy.close() to simulate trades based on your signals.
  2. request.security() — Pull data from other timeframes or symbols. This is how you build multi-timeframe confirmation logic.
  3. table.new() — Build summary tables that display in the chart corner. Useful for showing signal statistics without cluttering the chart.
  4. Pine Script v5 Type System — Understanding series float vs simple float vs const float eliminates most type errors.

TradingView's official Pine Script documentation is comprehensive and well-organized. The reference section lists every function with examples.

Get Started

Try TradingView — Free to Start

The free plan includes full Pine Script access. Build and test indicators on any chart without paying anything. Upgrade when the alert and indicator limits become a constraint.

Open TradingView Free →

Affiliate disclosure: We earn a commission if you upgrade to a paid plan. This doesn't affect what we recommend.

Free Weekly Newsletter

Get the Weekly Alpha Digest — free

Every week: the top AI trading signal that actually performed, one tool deep-dive, and one setup worth watching. No fluff, no spam.

No spam. Unsubscribe anytime. ~1,200 traders already subscribed.