How to Use TradingView Pine Script: Complete Guide 2025

How to Use TradingView Pine Script: Complete Guide 2025
Pine Script is TradingView's proprietary programming language that allows traders to create custom technical indicators, strategies, and alerts. Whether you're looking to automate your analysis or build unique trading tools, mastering Pine Script opens up powerful possibilities for your trading workflow.
In this comprehensive guide, you'll learn everything from basic syntax to creating your own indicators and strategies that can give you an edge in the markets.
What is Pine Script?
Pine Script is a domain-specific language (DSL) designed specifically for creating trading indicators and strategies on TradingView. It's lightweight, easy to learn, and integrates seamlessly with TradingView's charting platform.
Why Learn Pine Script?
Before diving into the technical details, let's understand why Pine Script is worth your time:
- Custom Indicators: Build personalized technical analysis tools tailored to your trading style
- Automated Strategies: Create and backtest trading strategies without manual calculations
- Alerts: Set up sophisticated alert conditions based on multiple criteria
- Community: Access thousands of open-source scripts and learn from other traders
- No Installation: Everything runs directly in your browser on TradingView
Prerequisites and What You'll Need
Getting Started
You'll need a TradingView account (free tier works for learning). Navigate to any chart, then click "Pine Editor" at the bottom of the screen to access the coding environment.
Required Setup
- TradingView Account: Sign up at TradingView.com (free accounts can save up to 3 indicators)
- Basic Understanding of Trading Concepts: Familiarity with candlesticks, moving averages, and basic indicators
- No Programming Experience Required: Pine Script is beginner-friendly, though any coding background helps
Step 1: Understanding Pine Script Basics
Script Structure
Every Pine Script begins with a version declaration and indicator/strategy definition:
//@version=5
indicator("My First Indicator", overlay=true)
// Your code goes here
plot(close)
Version Matters
Always use //@version=5 for new scripts. Version 5 is the latest and most feature-rich version of Pine Script with better performance and cleaner syntax.
Key Concepts
indicator() vs strategy()
- Use
indicator()for visual tools that plot on charts - Use
strategy()for backtestable trading systems
overlay Parameter
overlay=true: Draws directly on the price chartoverlay=false: Creates a separate pane below the chart
Step 2: Variables and Data Types
Declaring Variables
Pine Script uses a simple variable declaration syntax:
//@version=5
indicator("Variable Examples", overlay=true)
// Constant variable (cannot be reassigned)
myLength = 14
// Variable that can change using var keyword
var float myPrice = 0.0
myPrice := close
// Using input for user-configurable values
length = input.int(14, "MA Length", minval=1, maxval=200)
Common Data Types
| Type | Description | Example |
|---|---|---|
int | Whole numbers | 14, 200, -5 |
float | Decimal numbers | 3.14, close, high |
bool | True/False | true, close > open |
string | Text | "Buy Signal" |
color | Colors | color.red, #FF0000 |
Step 3: Built-in Variables and Functions
Essential Built-in Variables
Pine Script provides access to price data through built-in variables:
//@version=5
indicator("Price Data", overlay=false)
// OHLCV Data
plot(open, "Open", color=color.blue)
plot(high, "High", color=color.green)
plot(low, "Low", color=color.red)
plot(close, "Close", color=color.purple)
plot(volume, "Volume", color=color.orange)
Time-Based Variables
Use time, year, month, dayofweek, and hour for time-based conditions. For example: dayofweek == dayofweek.monday checks if it's Monday.
Common Built-in Functions
//@version=5
indicator("Built-in Functions Demo", overlay=true)
// Moving Averages
smaValue = ta.sma(close, 20) // Simple Moving Average
emaValue = ta.ema(close, 20) // Exponential Moving Average
// Other Indicators
rsiValue = ta.rsi(close, 14) // RSI
macdLine = ta.macd(close, 12, 26, 9) // MACD
// Mathematical Functions
highestHigh = ta.highest(high, 20) // Highest high over 20 bars
lowestLow = ta.lowest(low, 20) // Lowest low over 20 bars
plot(smaValue, "SMA 20", color=color.blue)
plot(emaValue, "EMA 20", color=color.red)
Step 4: Plotting and Visualization
Basic Plotting
//@version=5
indicator("Plotting Examples", overlay=true)
// Simple line plot
plot(ta.sma(close, 20), "SMA", color=color.blue, linewidth=2)
// Plot with style options
plot(ta.ema(close, 50), "EMA", color=color.red, style=plot.style_stepline)
Advanced Visualization
//@version=5
indicator("Advanced Plotting", overlay=true)
// Plotting shapes
plotshape(ta.crossover(ta.sma(close, 10), ta.sma(close, 20)),
style=shape.triangleup,
location=location.belowbar,
color=color.green,
size=size.small)
// Background color
bgcolor(close > open ? color.new(color.green, 90) : color.new(color.red, 90))
// Horizontal lines
hline(50, "Middle", color=color.gray, linestyle=hline.style_dashed)
Color Transparency
Use color.new(color.red, 80) to create transparent colors. The second parameter (0-100) controls transparency where 0 is opaque and 100 is fully transparent.
Step 5: Conditional Logic and Alerts
If Statements and Conditions
//@version=5
indicator("Conditional Logic", overlay=true)
smaShort = ta.sma(close, 10)
smaLong = ta.sma(close, 20)
// Ternary operator (inline if)
trendColor = smaShort > smaLong ? color.green : color.red
// If statement for complex logic
var string trendDirection = ""
if smaShort > smaLong
trendDirection := "Bullish"
else if smaShort < smaLong
trendDirection := "Bearish"
else
trendDirection := "Neutral"
plot(smaShort, color=trendColor, linewidth=2)
Creating Alerts
//@version=5
indicator("Alert Example", overlay=true)
fastMA = ta.sma(close, 10)
slowMA = ta.sma(close, 20)
// Detect crossovers
bullishCross = ta.crossover(fastMA, slowMA)
bearishCross = ta.crossunder(fastMA, slowMA)
// Visual signals
plotshape(bullishCross, style=shape.labelup, location=location.belowbar,
color=color.green, text="BUY")
plotshape(bearishCross, style=shape.labeldown, location=location.abovebar,
color=color.red, text="SELL")
// Alert conditions
alertcondition(bullishCross, "Bullish Crossover", "MA Bullish Cross detected!")
alertcondition(bearishCross, "Bearish Crossover", "MA Bearish Cross detected!")
Alert Setup
After adding your script to a chart, you must manually create alerts by right-clicking on the indicator and selecting "Add Alert." The alertcondition() function only defines the condition; it doesn't automatically send alerts.
Step 6: Building Your First Complete Indicator
Let's create a practical RSI with dynamic overbought/oversold zones:
//@version=5
indicator("Enhanced RSI", overlay=false)
// User inputs
rsiLength = input.int(14, "RSI Length", minval=1)
overbought = input.int(70, "Overbought Level", minval=50, maxval=100)
oversold = input.int(30, "Oversold Level", minval=0, maxval=50)
// Calculate RSI
rsiValue = ta.rsi(close, rsiLength)
// Determine color based on RSI level
rsiColor = rsiValue >= overbought ? color.red :
rsiValue <= oversold ? color.green : color.blue
// Plot RSI
plot(rsiValue, "RSI", color=rsiColor, linewidth=2)
// Plot reference lines
hline(overbought, "Overbought", color=color.red, linestyle=hline.style_dashed)
hline(oversold, "Oversold", color=color.green, linestyle=hline.style_dashed)
hline(50, "Middle", color=color.gray, linestyle=hline.style_dotted)
// Background color for extreme zones
bgcolor(rsiValue >= overbought ? color.new(color.red, 90) :
rsiValue <= oversold ? color.new(color.green, 90) : na)
// Alert conditions
alertcondition(ta.crossover(rsiValue, overbought), "RSI Overbought", "RSI entered overbought zone")
alertcondition(ta.crossunder(rsiValue, oversold), "RSI Oversold", "RSI entered oversold zone")
Step 7: Creating a Simple Trading Strategy
Strategies allow you to backtest your trading ideas:
//@version=5
strategy("MA Crossover Strategy", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=10)
// Inputs
fastLength = input.int(10, "Fast MA Length")
slowLength = input.int(20, "Slow MA Length")
// Calculate MAs
fastMA = ta.sma(close, fastLength)
slowMA = ta.sma(close, slowLength)
// Entry conditions
longCondition = ta.crossover(fastMA, slowMA)
shortCondition = ta.crossunder(fastMA, slowMA)
// Execute trades
if longCondition
strategy.entry("Long", strategy.long)
if shortCondition
strategy.close("Long")
// Plot MAs
plot(fastMA, "Fast MA", color=color.blue)
plot(slowMA, "Slow MA", color=color.red)
// Visual entry signals
plotshape(longCondition, style=shape.triangleup, location=location.belowbar, color=color.green)
plotshape(shortCondition, style=shape.triangledown, location=location.abovebar, color=color.red)
Backtesting Tips
After adding a strategy to your chart, click "Strategy Tester" tab at the bottom to see performance metrics including net profit, win rate, max drawdown, and detailed trade history.
Common Mistakes to Avoid
Repainting Issues
Avoid using security() with lookahead=barmerge.lookahead_on as it causes repainting - where signals appear in historical data but wouldn't have appeared in real-time. Always test strategies on live data before trading.
Common Errors
1. Forgetting var keyword: Variables without var reset on every bar. Use var to persist values.
2. Integer division: 5/2 equals 2, not 2.5. Use 5/2.0 for decimal results.
3. Comparing floats directly: Due to floating-point precision, use math.abs(a - b) < 0.0001 instead of a == b.
Performance Considerations
- Limit the use of
forloops; they can slow down script execution - Use built-in functions whenever possible - they're optimized for performance
- Avoid calculating the same value multiple times; store it in a variable
Advanced Tips and Techniques
Using Arrays
//@version=5
indicator("Array Example", overlay=true)
// Create an array to store recent closes
var float[] recentCloses = array.new_float(0)
// Add current close and limit size
array.push(recentCloses, close)
if array.size(recentCloses) > 10
array.shift(recentCloses)
// Calculate average of array
avgClose = array.avg(recentCloses)
plot(avgClose, "Avg of Last 10 Closes", color=color.purple)
Multi-Timeframe Analysis
//@version=5
indicator("MTF Example", overlay=true)
// Get daily close while on any timeframe
dailyClose = request.security(syminfo.tickerid, "D", close)
weeklyClose = request.security(syminfo.tickerid, "W", close)
plot(dailyClose, "Daily Close", color=color.blue, linewidth=2)
plot(weeklyClose, "Weekly Close", color=color.orange, linewidth=2)
Security Function Best Practices
When using request.security(), always use barmerge.lookahead_off (the default) for strategies to prevent future data from affecting historical signals.
Creating Custom Functions
//@version=5
indicator("Custom Function Example", overlay=true)
// Define a custom function
calculatePivot(h, l, c) =>
(h + l + c) / 3
// Use the function
pivotPoint = calculatePivot(high[1], low[1], close[1])
plot(pivotPoint, "Pivot Point", color=color.yellow, style=plot.style_circles)
Conclusion and Next Steps
You've now learned the fundamentals of Pine Script, from basic syntax to creating indicators and strategies. Here's what to do next:
- Practice: Modify the examples in this guide to reinforce your learning
- Explore: Browse TradingView's public script library for inspiration
- Read Documentation: TradingView's official Pine Script documentation is comprehensive
- Join the Community: The TradingView community forums are great for getting help
Keep Learning
The best way to master Pine Script is to start with a trading idea you want to test, then figure out how to code it. Real projects teach you faster than tutorials alone.
FAQ
Is Pine Script free to use?
Yes, Pine Script is completely free. You can write, test, and publish indicators on TradingView's free tier. However, free accounts are limited to 3 indicators per chart and some advanced features require a paid subscription.
Can I use Pine Script for automated trading?
Pine Script itself doesn't execute real trades - it's designed for analysis and backtesting on TradingView. However, you can use TradingView alerts with webhook functionality to connect to third-party services that execute trades on supported brokers.
How long does it take to learn Pine Script?
With basic programming knowledge, you can create simple indicators within a few hours. Becoming proficient enough to build complex strategies typically takes 2-4 weeks of consistent practice. The language is specifically designed to be accessible to traders without extensive coding backgrounds.
What's the difference between Pine Script v4 and v5?
Version 5 introduced significant improvements including: cleaner syntax, better function namespacing (e.g., ta.sma() instead of sma()), improved performance, new data types like maps, and enhanced error messages. New scripts should always use v5.
Can I convert Pine Script indicators to other platforms?
Pine Script is exclusive to TradingView. To use similar logic on other platforms (MetaTrader, ThinkOrSwim, etc.), you'll need to manually rewrite the code in that platform's language. There's no automated conversion tool.
Further Reading
Enjoying this article? Get more like it.
No spam, unsubscribe anytime.
Written by
John SmithJohn is a financial analyst and investing educator with over 10 years of experience in the markets.