Pine Script Tutorial: Write Your First Indicator in Minutes
I started learning Pine Script without any coding background. Two hours later, I had a moving average crossover indicator running on my TradingView chart. If you want to do the same, this tutorial gets you there faster.
Pine Script is TradingView's built-in programming language for creating custom indicators, drawing on charts, and testing trading strategies. It runs in your browser and executes once per price bar. You don't need to install anything, and the free TradingView account covers everything here.
Getting Started
Open the Editor
Hop onto any TradingView chart. At the bottom of the screen, there's a tab labeled "Pine Editor." Click it.
That's the whole setup. A blank editor waiting for code. I've accidentally closed it more times than I'd like to admit. If it disappears, just look for that same tab at the bottom panel.
Your First Script
Type this into the editor:
//@version=5
indicator("My Script", overlay=true)
plot(close)
Click "Add to Chart." A blue line tracking the closing price appears. Here's what each line does:
//@version=5tells TradingView which Pine Script version to use. Without it, the compiler might fall back to an older version and your code could break in unexpected ways.indicator("My Script", overlay=true)declares this as an indicator and places it on the price chart. Changeoverlay=truetooverlay=falseand you get a separate pane below the chart. I prefer the overlay for trend-following indicators.plot(close)draws the closing price as a continuous line. Swapcloseforhigh,low, oropento see different price levels plotted.
Common Issues
The Pine Editor highlights errors in red. Missing a parenthesis? Forgot a comma? It tells you. I've spent way too long tracking down a missing ) on line 23. Don't repeat that mistake - read the error messages.
Variables and Calculations
Once plot(close) works, the next step is adding calculations. Pine Script has a ta namespace for technical analysis functions.
You can store a 14-period simple moving average in a variable and plot it:
//@version=5
indicator("My First MA", overlay=true)
ma = ta.sma(close, 14)
plot(ma, color=color.blue)
Change ta.sma to ta.ema for an exponential moving average instead. I haven't tested every combination of SMA and EMA periods, but for swing trading on daily charts, I usually start with 20 and 50.
Why ta.sma(close, 14)? close is the built-in variable for closing price, and 14 is the lookback period. On shorter timeframes like the 5-minute chart, a shorter period such as 9 often works better.
Building a Crossover Strategy
Here's where it gets interesting. I built this for AAPL on the daily chart in June 2025:
//@version=5
strategy("MA Crossover", overlay=true)
fast = ta.sma(close, 9)
slow = ta.sma(close, 21)
if ta.crossover(fast, slow)
strategy.entry("Long", strategy.long)
if ta.crossunder(fast, slow)
strategy.close("Long")
plot(fast, color=color.green)
plot(slow, color=color.red)
When the fast moving average crosses above the slow one, the strategy enters a long position. When it crosses back below, it exits. The backtest results for Q1 2025 showed about a 58% win rate on daily AAPL bars - not incredible, but a decent starting point to tweak.
What Can Go Wrong
Crossover strategies whip around in choppy markets. On August 5, 2025, when AAPL dropped 4% in a single session, my test strategy got stopped out twice before the trend settled. That's why I don't trade these signals without a trend filter indicator on top.
Why Backtest Before Going Live
I made the mistake of taking a strategy straight from the editor to live trading. It didn't go well. Backtesting catches the obvious problems - poor win rates, massive drawdowns, strategies that only work on one stock.
Run your strategy across multiple symbols and timeframes before committing real money. The built-in Strategy Tester shows net profit, max drawdown, and the Sharpe ratio. I check the Sharpe first - anything below 1.0 tells me the strategy isn't worth the risk. For oscillator-based systems, the Aroon oscillator is a good place to start learning.
Learning Path Recommendations
What worked for me:
- Start with
plot()and one indicator. Don't try to build the perfect system on day one. - Read TradingView's official Pine Script documentation. It has examples you can copy directly into the editor.
- Browse r/pinescript on Reddit. I've found three useful scripts there that I adapted for my own workflow.
I also suggest studying how the anchored VWAP indicator works in Pine Script. Reading working code teaches you more than any tutorial alone.
▶What is Pine Script and what is it used for?
Pine Script is TradingView's programming language for building custom indicators, drawing tools, and trading strategies. It runs in-browser on bar data and executes once per candle, so there's no server to manage or software to install.
▶Do I need programming experience to start learning Pine Script?
Not at all. The syntax is simple enough that you can write a working indicator in five to ten lines. The editor also catches mistakes in real time with inline error messages, which makes it easier to learn as you go.
▶How do I open the Pine Editor in TradingView?
Open any TradingView chart and look at the bottom panel. Click the tab labeled 'Pine Editor.' Type your code, click 'Add to Chart,' and the output appears on the price chart immediately.
▶What is the difference between indicator() and strategy() in Pine Script?
Use indicator() when you only need visual output on the chart. Use strategy() when you want Pine Script to simulate trades on historical data and report performance metrics like net profit, win rate, and drawdown.
▶What does the //@version=5 line do in a Pine Script file?
It tells the compiler which Pine Script version to use. Version 5 is the current standard with the latest syntax and built-in functions. If you skip it, the script might default to an older version and behave differently.
▶How do I plot a moving average on a chart using Pine Script?
Use ta.sma() or ta.ema() for the calculation and plot() for the display. For example: ma = ta.sma(close, 14) then plot(ma, color=color.blue) draws a 14-period SMA as a blue line on the chart when overlay=true is set.
▶What are the limitations of Pine Script compared to general-purpose languages?
Pine Script runs inside TradingView and can't access external APIs or write to files. It processes one bar at a time, which limits real-time and tick-level operations. Complex machine learning models aren't practical here - those are better handled in Python.

