◆ New — Strategy Validator, Code Fixer & Prop Compliance Checker are live. Try one free →
Home / Learn / Pine Script for Beginners: Your First Indicator
Pine Script

Pine Script for Beginners: Your First Indicator

A friendly, step-by-step walkthrough of Pine Script for beginners: opening the Pine Editor, writing your first //@version=6 script, declaring an indicator, adding inputs, and plotting a simple EMA on your chart. This article is educational only and not financial advice; nothing here describes a profitable system, and trading always involves the risk of loss. The goal is to make you comfortable reading and writing clean, correct Pine v6 code.

What Pine Script Is (and What This Guide Covers)

If you have ever wanted to add your own lines, labels, or moving averages to a TradingView chart, Pine Script is the language that makes it possible. It is a small, purpose-built language for describing what to draw on a price chart and when to draw it. You do not need prior programming experience to get started, which is exactly why Pine Script for beginners is such a popular first step into chart customization.

The key idea to hold in your head is that Pine runs once per bar. A chart is just a sequence of candles (bars), and your script re-runs from top to bottom on every one of them. Variables like close, open, high, and low automatically refer to the current bar's values as the script walks across history and into the live candle. This "runs on every bar" model feels unusual at first, but it quickly becomes second nature.

In this guide we will build one complete, working indicator: a single Exponential Moving Average (EMA) plotted on top of price. Along the way you will meet the four things every beginner script needs — the version line, the indicator() declaration, an input.* for settings, and a plot() to draw something. By the end you will be able to read most simple scripts you find and write small ones of your own.

A quick note before we start: this article is educational only and not financial advice. A moving average is a descriptive tool — it summarizes recent prices. It does not predict the future, and no indicator removes the risk of loss inherent in trading. We are learning the language, not chasing returns.

Opening the Pine Editor

Everything happens inside TradingView's Pine Editor, a code panel built right into the charting interface. Open any chart, then look along the bottom toolbar for the Pine Editor tab and click it. A panel slides up from the bottom of the screen with a text area on the left for your code and an Add to chart button in the top-right corner.

When you open a fresh editor, TradingView usually drops in a tiny starter template. Do not worry about understanding it yet — we are going to clear it out and write our own from scratch so every line means something to you. Select all the existing text and delete it so you have an empty editor to type into.

The two buttons you will use most are Add to chart, which compiles your script and overlays it on the current chart, and Save, which stores the script under a name so you can reuse it later. If your code has a mistake, TradingView will not add it to the chart; instead a small red marker and an error message appear at the bottom of the editor, pointing you at the line to fix. Treat those messages as helpful directions rather than failures — even experienced authors lean on them constantly.

One habit worth forming early: change your chart's symbol or timeframe after adding a script and watch what happens. Your indicator recalculates automatically for whatever data is on screen. That instant feedback loop is the best way to build intuition about what your code actually does.

The Three Lines Every Script Starts With

Almost every beginner indicator opens with the same small scaffold. Let's write it and then read it line by line.

//@version=6
indicator("My First Indicator", overlay = true)
plot(close)

The first line, //@version=6, tells TradingView which version of the language to use. It looks like a comment because it starts with //, but it is a special directive and it must be the very first line of your script. Always pin yourself to version 6 — it is the current generation of Pine, and mixing older syntax with it is one of the most common sources of confusing errors for newcomers.

The second line declares what kind of script this is. indicator() says "this script draws information on a chart" (as opposed to a strategy(), which simulates entries and exits — a topic for later). The first argument is the title that shows up on your chart. The named argument overlay = true tells TradingView to draw on top of the price candles rather than in a separate pane below them. For a moving average, which lives in the same price range as the candles, overlay = true is exactly what we want.

The third line, plot(close), draws a line connecting the closing price of every bar — effectively a line chart of price. plot() is the workhorse drawing function in Pine: you hand it a series of numbers, one value per bar, and it connects the dots. Click Add to chart now and you should see a line tracing your candles' closes. That is a complete, valid Pine v6 indicator. Everything else we do is refinement.

Adding Inputs So Settings Are Adjustable

Hard-coding numbers directly into a script works, but it is inflexible. If you wanted a 20-period average today and a 50-period one tomorrow, you would have to edit the code each time. The input.* family solves this by creating settings that appear in the indicator's gear-icon menu on the chart, so you (or anyone using your script) can change them without touching code.

The most common one for a beginner is input.int(), which produces a whole-number setting. You give it a default value, a friendly title, and optional bounds:

//@version=6
indicator("EMA Example", overlay = true)

length = input.int(20, title = "EMA Length", minval = 1)

Reading that line: we create a variable called length, set its default to 20, label it "EMA Length" in the settings menu, and use minval = 1 to stop anyone from entering zero or a negative number (which would make no sense for a length). After you add this to the chart, click the gear icon next to the indicator's name and you will see your "EMA Length" field, ready to adjust.

There is a whole family to explore as you grow — input.float() for decimals, input.bool() for on/off checkboxes, input.source() to let users pick close versus open, and input.color() for styling. The pattern is always the same: the input call returns a value, you store it in a variable, and you use that variable in your calculations. Inputs are what turn a one-off script into a flexible, reusable tool.

Building and Plotting Your First EMA

Now we put the pieces together. An exponential moving average smooths price by weighting recent bars more heavily than older ones. In Pine v6 you do not write the math by hand — there is a tested built-in: ta.ema(). The ta. prefix is a namespace; it groups all the technical-analysis functions together (ta.sma, ta.rsi, ta.atr, and many more). Using the namespaced name is required in v6 — a bare ema() will not compile.

Here is the complete, working indicator:

//@version=6
indicator("My First EMA", overlay = true)

// User-adjustable setting
length = input.int(20, title = "EMA Length", minval = 1)

// Calculate the EMA of the closing price
emaValue = ta.ema(close, length)

// Draw it on the chart
plot(emaValue, title = "EMA", color = color.orange, linewidth = 2)

Walk through it once more so nothing is mysterious. The version line pins us to v6. indicator(... overlay = true) puts our drawing on the price candles. input.int() gives us an adjustable length. ta.ema(close, length) computes the EMA of closing prices over that length and stores one value per bar in emaValue. Finally, plot() draws that series as a 2-pixel orange line with a clean title. Click Add to chart and an orange EMA glides across your candles.

A small but important point about trust: because ta.ema() only ever uses the current and past bars, this script does not "repaint" or peek at future data — what you see on a historical bar is what you would have seen live. That non-repainting behavior is a quality you should always check for as your scripts grow more complex; subtle look-ahead and repainting bugs are exactly the kind of issue that tooling like ForexCodes' Audit can flag for you. For a plain EMA plot, though, you are already on solid ground.

Keep experimenting from here. Add a second plot() with a longer length to compare a fast and slow average, swap ta.ema for ta.sma to feel the difference, or change the color. Just remember the framing we started with: these are tools for describing price, learned here for education only and not as financial advice. Moving averages lag, markets are uncertain, and trading carries a real risk of loss — so treat your first indicator as a window into the language, and let curiosity, not hype, guide what you build next.

Key takeaways

Educational only — not financial advice. Trading involves substantial risk of loss.

Catch the bug that compiles.Run auditGet Pro