This article guides you through creating custom trading indicators on TradingView using PineScript. It explains TradingView's purpose, PineScript's basics, data types, series, functions, control flow, and more. It then demonstrates building a Relative Strength Index (RSI) indicator step by step, showing how to code and test it, and how to publish and share it with the TradingView community. The article encourages readers to explore PineScript further and use its capabilities to develop their trading indicators.
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.
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 it 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:
Series
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
Operators
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
Functions
Reusable blocks of code to execute specific tasks:
// Built-in function
ema20 = ta.ema(close, 20)
// Custom function
foo() =>
int sum = 10 + 15
sum
// Call function
value = foo()
Control Flow
Control execution path based on conditional logic:
// If/else statement
if close > open
// Bull candle
else
// 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 (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 an 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".
//@version=5
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.
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 to 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!
//@version=5
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.
Conclusion
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!
If you like my article, feel free to follow me on HackerNoon.
The lead image for this article was generated by HackerNoon's AI Image Generator via the prompt "Illustrate arbitrary financial charts"