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
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!
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:
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.
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.
Pine Script has four built-in series for OHLC data:
For example:
// Access close of current bar
currentClose = close
// Access open two bars ago
pastOpen = open[2]
You can declare your own series to store custom indicator values:
// Declare series
var mySeries = na
// Assign values
mySeries := close
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 only exist for visible bars on the chart. If you scroll left or right, the series values are recalculated.
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)
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
sum
// Call function
value = foo()
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!
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:
Let's break down the step-by-step process:
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.
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.
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.
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.
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.
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:
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.
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.
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:
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)
In the Pine Editor, click Add to Chart at the bottom. This will load the indicator on a price chart.
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.
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.
TradingView makes it simple to save your PineScript creation and share it on their public indicator library:
In the Pine Editor, click Save As. Give your indicator a descriptive name and save it.
In the indicator settings, change Visibility to Public.
Provide an explanation of what your indicator does in the Description field.
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!
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"