PineScript 101: Learn to Write Your First TradingView Indicator

Learn to write Pinescript v5 and create your first TradingView indicator. Enhance your trading strategies and gain a competitive edge in the market!

Hey friends! Have you ever wanted to create your own custom indicators for TradingView? Well, you're in luck - in this post, I'll be walking you through a step-by-step guide on how to write a basic indicator from scratch using PineScript.

For those who don't know, TradingView is a popular online charting platform used by traders to analyze financial markets. It allows you to create charts with various indicators and drawing tools, and also features a huge community of traders who publish ideas and custom indicators.

PineScript is the built-in coding language used on TradingView to program your own indicators and strategies. It's pretty straightforward to learn, especially if you have any coding experience. I'll be focusing on PineScript version 5 which is the latest iteration with new features and improvements.

So let's get started and get familiar with PineScript syntax, code your first basic indicator, and publish it for the community - by the end, you'll have the skills to bring any custom indicator idea to life!

Setting Up Your TradingView Account

The first step is to head over to Tradingview and sign up for a free account. The free plan is enough to follow this tutorial and publish an indicator.

Once you log in, you'll see the TradingView charting homepage. The Chart tab is where you'll spend time analyzing price charts from global markets. The Pine Editor is where we'll code the indicator script.

With your account created and the platform explored, you now have everything needed to start coding a custom indicator. Time to move on to learning PineScript!

Introducing PineScript

PineScript is a programming language specific to TradingView that lets you create trading algorithms, indicators, strategies and more. It uses a JavaScript-like syntax to build scripts that run natively in the TradingView charting environment.

Some key facts about PineScript:

  • Used only on TradingView, interpreted and executed by their servers
  • Built-in variables and functions tailored for financial data analysis
  • PineScript v5 is the latest version with new features
  • Open-source with a large community contributing scripts

To access the Pine Code Editor, click on the Pine Editor tab at the top. This will open up a blank editor panel where you can start coding your indicator. Think of this as your workbench to build custom PineScript programs.

Pine Editor

When you first open the editor, you'll see a sample script with some basic code to show variable assignments, a plot function, etc. You can leave it for reference or delete and start fresh.

Now before we jump into writing code, let's get familiar with some PineScript basics.

Understanding the Basics of PineScript

PineScript shares similarities with languages like JavaScript and C in both syntax and functionality. Let's go over some key concepts and components that we'll need for our first indicator:


A series in Pine Script refers to sequential data like OHLC prices, indicator values, trade volumes etc over a timeframe. It is the foundation for accessing and manipulating data in your scripts.

Core price series

Pine Script has four built-in series for OHLC data:

  • open - Open price of each bar
  • high - High price of each bar
  • low - Low price of each bar
  • close - Close price of each bar

For example:

// Access close of current bar
currentClose = close

// Access open two bars ago
pastOpen = open[2]

Declaring custom series

You can declare your own series to store custom indicator values:

// Declare series 
var mySeries = na

// Assign values
mySeries := close

Accessing prior values

Use array index notation to access historical values in a series:

// Close 1 bar ago
prevClose = close[1] 

// Close 5 bars ago
pastClose = close[5]

Series lifespan

Series only exist for visible bars on the chart. If you scroll left or right, the series values are recalculated.

Common operations

You can perform math, combine series, find minimum/maximum etc:

// Add two series
sum = series1 + series2

// Higher value of two series
hi = math.max(series1, series2)

// Moving average of series
sma = sma(mySeries, 20)

Data Types

Explicitly declare variables with types:

// Integer
var int myInteger = 10

// Float
var float myFloat = 10.5 

// String 
var string myString = "Hello"

// Boolean
var bool myBool = true


Perform actions like arithmetic, comparisons, etc:

// Arithmetic
int sum = 10 + 15
int diff = 20 - 7
int product = 2 * 10

// Comparison 
if close > open
    // Do something

// Logical  
if (trend == "up") and (momentum > 100)
    // Do something


Reusable blocks of code to execute specific tasks:

// Built-in function
ema20 = ta.ema(close, 20)

// Custom function
foo() => 
    int sum = 10 + 15

// Call function
value = foo()

Control Flow

Control execution path based on conditional logic:

// If/else statement
if close > open
    // Bull candle
    // Bear candle

// For loop  
for i=0 to 10
    // Do something

// While loop
while close > open
    // Uptrend

That covers some of the key concepts. Don't worry if the syntax seems strange - it will start to feel natural with examples. Now let's shift gears and actually build out an indicator!

Building Your First Indicator

Now that we have covered the basics of Pine Script, let's shift gears and walk through building a practical trading indicator from scratch.

In this example, we will code a Relative Strength Index (RSI) indicator. The RSI is a popular momentum oscillator used by traders to identify overbought and oversold conditions.

Here is an overview of how RSI works:

  • Calculates the speed and rate of price changes
  • Fluctuates between 0 and 100
  • Values over 70 indicate overbought state
  • Values under 30 indicate oversold state
  • Used to detect reversals or divergence

Let's break down the step-by-step process:

Step 1 - Declare A Script

First, let's define a version of PineScript to V5 and then name out indication "RSI".

indicator("RSI", overlay=false)

overlay=true indicates that we don't intend for this indicator to overlay the chart.

Step 2 - Define User Inputs

We want to allow the user to customize the RSI period length. We use the input() function:

// RSI Period Input
period = input(title="RSI Period", type=input.integer, defval=14)

The input() function creates a configurable setting the user can change.

Step 3 - Declare RSI Variable

We need a variable to store the RSI value on each bar:

// RSI series 
var rsi = na

The na value initializes it to not applicable before the first value.

Step 4 - Calculate RSI in Function

In a separate function, we code the RSI calculation logic:

// RSI calculation
rsi(period) =>

    up = ta.rma(math.max(ta.change(close), 0), period)
    down = ta.rma(-math.min(ta.change(close), 0), period)
    rsi := down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))

This uses the change() and rma() functions to calculate the relative strength.

Step 5 - Plot RSI on Chart

Next we visualize the RSI as a line on the chart:

// Plot 
plot(rsi, title="RSI", style=plot.style_line, linewidth=2, color=#FF7200)

We style it with a thicker line in orange color.

Step 6 - Add Overbought/Oversold Levels

Finally, we draw horizontal lines at 70 and 30 for overbought/oversold reference:

// Upper band
h1 = hline(70, "Upper Band", color=#C0C0C0)

// Lower band
h2 = hline(30, "Lower Band", color=#C0C0C0)

And that's it! We now have a complete RSI indicator coded from scratch in Pine Script.

Obviously this was a very simple example just to demonstrate the basics. You can enhance it further with more configuration options, optimization, alerts, etc. But you should now have a sense of how to go from idea to coded indicator in PineScript.

Here are two ways we could add more features to the RSI indicator example using tables and alerts:

1. Create RSI Values Table

We can store the RSI values in a table for easy reference:

// Define RSI table
table rsiTable(symbol, rsi) 

// On each bar record RSI
table.push(rsiTable, symbol, rsi)

Now the user can see all the exact RSI numbers in the data window rather than just the chart line.

2. Add Overbought/Oversold Alerts

We can trigger alerts when RSI crosses above 70 or below 30:

// Overbought alert
if rsi > 70
    alert("RSI Overbought!")
// Oversold alert  
if rsi < 30
    alert("RSI Oversold!")

This allows traders to get real-time notifications when the indicator signals important overbought or oversold conditions.

The table provides historical data access and alerts create actionable signals - both useful for traders using the RSI indicator. There are many possibilities like these to expand indicators beyond just visualization on the chart.

Here is the complete code!

indicator("RSI", overlay=false)

// User Input
period = input(title="RSI Period", type=input.integer, defval=14)

// RSI Series
var rsi = na

// RSI Calculation
rsi(period) =>

    up = ta.rma(math.max(ta.change(close), 0), period)
    down = ta.rma(-math.min(ta.change(close), 0), period)
    rsi := down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down)) 

// Plot RSI	
plot(rsi, title="RSI", style=plot.style_line, linewidth=2, color=#FF7200)

// Overbought Level
h1 = hline(70, "Upper Band", color=#C0C0C0)

// Oversold Level
h2 = hline(30, "Lower Band", color=#C0C0C0)

// RSI Table
table rsiTable(symbol, rsi)
table.push(rsiTable, symbol, rsi)

// Alerts
if rsi > 70
    alert("RSI Overbought!")
if rsi < 30
    alert("RSI Oversold!")

Next let's walk through testing your script and publishing it for the TradingView community.

Configuring and Testing the Indicator

Before our EMA indicator is ready to publish, we need to configure it and test it works as expected.

TradingView makes this easy through their charting environment:

1. Add basic settings

Let's allow customization of the EMA line color and thickness:

// Color setting
col = input(title="Color", type=input.color, defval=#2962FF)

// Thickness 
thm = input(title="Thickness", type=input.integer, defval=2)

// Update plot function
plot(ema_values, "EMA", color=col, linewidth=thm)

2. Add script to a chart

In the Pine Editor, click Add to Chart at the bottom. This will load the indicator on a price chart.

3. Observe indicator values

Change the symbol and timeframe. Ensure the EMA line plots as expected. Tweak the length and smoothing inputs and see the effect.

To inspect the actual EMA values being calculated, you can use the plotchar() function to print values on the chart:

// Print EMA values on chart
plotchar(ema_values, "EMA", "▲", location.bottom)

The data window also provides the ability to see all indicator values for debugging. Open the data window and look for your "EMA" series.

4. Debug issues

If the indicator prints any errors or behaves strangely, go back and debug the script. Fix any typos, logic errors, etc.

Checking the printed EMA values compared to the chart can help identify and resolve calculation problems. The data window lets you inspect the exact EMA numbers at each bar to ensure accuracy.

Publishing and Sharing the Indicator

TradingView makes it simple to save your PineScript creation and share it on their public indicator library:

1. Save script

In the Pine Editor, click Save As. Give your indicator a descriptive name and save it.

2. Set visibility to public

In the indicator settings, change Visibility to Public.

3. Add description

Provide an explanation of what your indicator does in the Description field.

4. Get community feedback

Publish your indicator and encourage other users to try it out! Observe their ratings and feedback to improve it over time.

And that's all it takes to unleash your TradingView indicator with the world! PineScript has a supportive community, so leverage resources like the PineCoders chat room and wiki to continue enhancing your creation.


If you've made it this far - congratulations! You now have the skills to code a custom indicator from scratch using PineScript.

Of course this was just a quick overview to get you started. There's a whole lot more you can explore with PineScript like trading strategies, visualizations, integrations and more. I hope this tutorial gave you a solid foundation to unleash your creativity!

So now it's your turn - open up that Pine Editor, get coding, and bring your unique indicator ideas to life. The PineScript community can't wait to see and use what you build. Feel free to reach out if you have any other questions. Happy coding!

Subscribe to JS Dev Journal

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.