Introduction
Without the right trading tools, you canât conduct effective technical analysis. A strong trading strategy will help you avoid common mistakes, improve your risk management, and increase your ability to identify and take advantage of opportunities.
For many, TradingView is the go-to charting platform. Offering a hub of technical analysis tools, the powerful HTML5 web application is used by millions to track movements in the Forex, cryptocurrency, and traditional stock markets.
TradingView has many powerful features: it allows us to track assets across numerous trading platforms and to publish trading ideas within its social network. In this article, weâll focus on its customizability. Weâll be using Pine Script, TradingViewâs own programming language, which grants us granular control over our chart layouts.
Letâs get started!
What is Pine Script?
Pine Script is a scripting language that can be used to modify your TradingView charts. The platform already equips you with many features to do so, but Pine Script allows you to take it a step further. Whether you want to change the colors of your candlesticks or to backtest a new strategy, the Pine Editor will enable you to customize your real-time charts as you see fit.
The code itself is excellently documented, so be sure to check out the user manual for more information. Our goal in this tutorial is to discuss some of the basics and introduce indicators that can come in handy for cryptocurrency trading.
Setting up
Itâs incredibly simple to get started with Pine Script. Any code we write is run on TradingViewâs servers, so we can access the editor and develop our scripts from a browser â without any additional download or configuration required.
In this tutorial, weâre going to chart the Bitcoin/Binance USD (BTCBUSD) currency pair. If you donât have one already, go ahead and create a free account (thereâs a pro subscription available, too, but it isnât necessary for this guide).Â
Follow this link, and youâll see a chart resembling the following:
Yours will probably be more up to date.
Here, we want to get the full-featured chart â click on the button to access it. That gives us a much more detailed view, drawing tools, and options to plot trendlines, amongst other things.
The full-featured chart. You can adjust the timeframe by clicking on the views above the highlighted tabs.
We wonât be discussing how to use the various tools available, but if youâre serious about technical analysis, we highly advise that you familiarize yourself with them. On the bottom left (outlined in the image), youâll see a few different tabs â click on Pine Editor.
The Pine Editor
This editor is where the magic happens. Weâll tell it what we want to do, then click on Add to Chart to see our annotations appear above. Note that things can get messy if we include several annotations at once, so weâll remove them between examples (right-click in the chart > Remove Indicators).
You can see that we already have a couple of lines of code there. Letâs click Add to Chart to see what happens.
A second chart gets added beneath the original. The new chart happens to represent the same data. Hover over My Script and click on the cross to remove it. Now, letâs dig into the code.
study("My Script")
This first line is just setting up our annotation. It only requires the name that you want to call the indicator ("My Script", in this case), but there are also some optional parameters we can add. One of those is overlay, which tells TradingView to place the indicator on the existing chart (instead of in a new segment). As you can see from our first example, it defaults to false. Though we wonât see it in action now, overlay=true adds the indicator to the existing chart.
plot(close)
This line is the instruction to plot the close price of Bitcoin. plot simply gives us a line chart, but we can also display candlesticks and bars, as weâll see shortly.Â
Now, letâs try the following:
//@version=4
study("My Script", overlay=true)
plot(open, color=color.purple)
Once you add this, you should see a second chart (which looks like the original shifted to the right). All weâve done is plotted the open price instead, and since the current dayâs open is the previous dayâs close, it makes sense that these have an identical shape.
Okay! Letâs get rid of the current annotations (remember, we do that by right-clicking and hitting Remove Indicators). Hover over Bitcoin / BUSD and click the Hide button to clear the current chart, too.
Many traders prefer candlestick charts as they give us more information than a simple plot like the one we just did. Letâs add them next.Â
//@version=4
study("My Script", overlay=true)
plotcandle(open, high, low, close)
Itâs a good start, but the lack of colors makes it a bit bland. Ideally, we should have red candles when the open is greater than the close for the given timeframe, and green ones if the close exceeds the open. Weâll add a line above the plotcandle() function:
//@version=4
study("My Script", overlay=true)
colors = open >= close ? color.red : color.green
plotcandle(open, high, low, close)
This looks at every candlestick and checks whether the open is greater or equal to the close. If it is, it means prices have dropped over the period, so it will color the candlestick red. Otherwise, it will color it green. Modify the plotcandle() function to pass this color scheme in:
//@version=4
study("My Script", overlay=true)
colors = open >= close ? color.red : color.green
plotcandle(open, high, low, close, color=colors)
Remove the current indicators if you havenât already, and add this one to the chart. Now we should have something resembling a regular candlestick chart.
Beautiful!
Plotting moving averages (MA)
Weâve got some of the basics down. Letâs move on to our first custom indicator â the exponential moving average, or EMA. This is a valuable tool as it allows us to filter out any market noise and smooth out price action.Â
EMA differs slightly from the simple moving average (SMA), in that it puts more weight in the most recent data. It tends to be more reactive to sudden movements and is often used for short-term plays (in day trading, for example).
The simple moving average (SMA)
We might as well plot the SMA, just so we can compare the two after. Add this line to your script:
plot(sma(close, 10))
This plots the average of the previous ten days. Tweak the number in the brackets to see how the curve changes when taking into account different lengths.
The SMA, based on the previous ten days.
The exponential moving average (EMA)
The EMA will be a bit trickier to understand, but not to worry. Letâs break down the formula first:
EMA = (Close - Previous Dayâs EMA) * Multiplier - Previous Dayâs EMA
So, whatâs this telling us? Well, for each day, we calculate a new moving average based on the previous dayâs one. The multiplier is what âweighsâ the most recent period, and is calculated with the following formula:
Multiplier = 2 / (Length of EMA + 1)
As with simple moving averages, we need to specify how long the EMA will be. Syntactically, the function to plot EMA is similar to the SMA one. Plot it alongside the SMA so you can compare the two:
//@version=4
study("My Script", overlay=true)
plot(sma(close, 10))
plot(ema(close,10))
You can see a slight difference in the two types of MA.
â Â Looking to get started with cryptocurrency? Buy Bitcoin on Binance!
Built-in scripts
So far, weâve written our code manually so you can get a feel for it. But letâs introduce something that can save us time, particularly if weâre writing more complex scripts, and we donât want to do them from scratch.
On the top, right-hand side of your editor, click on New. Youâll get a dropdown menu with all kinds of different technical indicators. Click Moving Average Exponential to see the source code for an EMA indicator.
Go ahead and add this to the chart.
This one is different from ours â youâll notice the input() functions. These are nice from a usability perspective since you can click on this boxâĻ
...and easily change some of the values in a pop-up window by clicking on the Settings wheel.
Weâll add a couple of input() functions in our next script to demonstrate this.
Plotting the Relative Strength Index (RSI) indicator
The Relative Strength Index (RSI) is another essential indicator in technical analysis. Itâs known as a momentum indicator, meaning that it measures the rate at which assets are bought and sold. Presented on a scale of 0 to 100, an RSI score attempts to inform investors on whether assets are overbought or oversold. Typically, an asset may be considered oversold if it has a score less than or equal to 30, and it could be overbought with a score greater or equal to 70.
If you head to New > RSI Strategy, you can see this for yourself. RSI is generally measured over periods of 14 (i.e., 14 hours or 14 days), but youâre free to tweak that setting to suit your own strategy.
Add this to the chart. You should see a few arrows displayed now (defined by the strategy.entry() function in the code). RsiLE indicates a potential opportunity to long the asset as it may be oversold. RsiSE highlights possible points at which to short the asset when itâs overbought. Note that, as with all indicators, you shouldnât necessarily rely on these as foolproof evidence that prices will decrease/increase.
Backtesting
There is a way for us to test our custom indicators. Though past performance is no guarantee of future results, backtesting our scripts can give us an idea of how effective they are at picking up signals.Â
Weâll give an example of a simple script below. Weâre going to create a straightforward strategy that enters a long position when the BTC price falls below $11,000 and exits the position when the price exceeds $11,300. We can then see how profitable this strategy would have been historically.
//@version=4
strategy("ToDaMoon", overlay=true)
enter = input(11000)
exit = input(11300)
price = close
if (price <= enter)
   strategy.entry("BuyTheDip", strategy.long, comment="BuyTheDip")
if (price >= exit)
  strategy.close_all(comment="SellTheNews")
Here weâve defined entry and exit as variables â both are inputs, meaning that we can change them on the chart later. We also set up the price variable, which takes the close for each period. Then, we have some logic in the form of if statements. If the part in brackets is true, then the indented block beneath it will be run. Otherwise, it will be skipped.
So, if the price is less than or equal to our desired entry, the first expression evaluates as true, and weâll open a long position. Once the price equals or exceeds the desired exit, the second block will be triggered, closing all open positions.Â
Weâll annotate the chart with arrows that show where weâve entered/exited, so weâve specified what to label these points with the comment parameter (in this example, âBuyTheDipâ and âSellTheNewsâ). Copy the code, and add it to the chart.
You can now see the indicators on the chart. You might need to zoom out.
TradingView automatically applies your rules to older data. Youâll also notice that it switches from the Pine Editor to the Strategy Tester tab. This allows you to see an overview of your potential profits, a list of trades, and each of their individual performances.
Positions weâve entered and exited.
Tying it together
Time to write our own script by using some of the concepts weâve seen so far. Weâre going to combine EMA and RSI and use their values to color candlesticks, yielding insights that we can easily visualize.Â
This shouldnât be construed as financial advice â thereâs no objectively correct way to use this indicator. As with all others, it should be used with other tools to develop your own strategy.
Now letâs work on our new script. Remove all your indicators from the chart, and hide the Bitcoin/BUSD chart, too, so that we have a clean canvas to work on.
Letâs start by defining our study. Feel free to name it whatever you want, just make sure to set overlay=true.
study(title="Binance Academy Script", overlay=true)
Remember our EMA formula from earlier. We need to provide the multiplier with the length of the EMA. Letâs make it an input that requires an integer (so, no decimal places). Weâll also set a minimum that it can be (minval), and a default value (defval).
study(title="Binance Academy Script", overlay=true)
emaLength = input(title="EMA Length", type=input.integer, defval=25, minval=0)
Using this new variable, we can calculate the EMA value for each candle in our chart:
study(title="Binance Academy Script", overlay=true)
emaLength = input(title="EMA Length", type=input.integer, defval=25, minval=0)
emaVal = ema(close, emaLength)
Great. Onto the RSI. Weâll give it a length in a similar way:
study(title="Binance Academy Script", overlay=true)
emaLength = input(title="EMA Length", type=input.integer, defval=25, minval=0)
emaVal = ema(close, emaLength)
rsiLength = input(title="RSI Length", type=input.integer, defval=25, minval=0)
And now, we can calculate it:
study(title="Binance Academy Script", overlay=true)
emaLength = input(title="EMA Length", type=input.integer, defval=25, minval=0)
emaVal = ema(close, emaLength)
rsiLength = input(title="RSI Length", type=input.integer, defval=25, minval=0)
rsiVal = rsi(close, rsiLength)
At this stage, letâs put together the logic that colors the candlesticks depending on the EMA and RSI values. Letâs take a situation where (a) the close price of the candle exceeds the EMA and (b) where the RSI is above 50.
Why? Well, you might decide that these indicators can be used in conjunction to tell you when to long or short Bitcoin. For instance, you might think that satisfying both of these conditions means that itâs a good time to enter a long position. Or conversely, you might use it to inform you when not to short, even if other indicators say otherwise.
So, our next line will look like this:
study(title="Binance Academy Script", overlay=true)
emaLength = input(title="EMA Length", type=input.integer, defval=25, minval=0)
emaVal = ema(close, emaLength)
rsiLength = input(title="RSI Length", type=input.integer, defval=25, minval=0)
rsiVal = rsi(close, rsiLength)
colors = close > emaVal and rsiVal > 50 ? color.green : color.red
If we translate this into plain English, weâre merely saying that if the EMA value exceeds the close price and the RSI score exceeds 50, weâll color the candle green. Otherwise, weâll color it red.Â
Next, plot the EMA:
study(title="Binance Academy Script", overlay=true)
emaLength = input(title="EMA Length", type=input.integer, defval=25, minval=0)
emaVal = ema(close, emaLength)
rsiLength = input(title="RSI Length", type=input.integer, defval=25, minval=0)
rsiVal = rsi(close, rsiLength)
colors = close > emaVal and rsiVal > 50 ? color.green : color.red
plot(emaVal, "EMA")
Lastly, plot the candles, making sure to include the color parameter:
study(title="Binance Academy Script", overlay=true)
emaLength = input(title="EMA Length", type=input.integer, defval=25, minval=0)
emaVal = ema(close, emaLength)
rsiLength = input(title="RSI Length", type=input.integer, defval=25, minval=0)
rsiVal = rsi(close, rsiLength)
colors = close > emaVal and rsiVal > 50 ? color.green : color.red
plot(emaVal, "EMA")
plotcandle(open, high, low, close, color=colors)
And thatâs the script! Add it to the chart to see it in action.
A BTC/BUSD chart with the EMA/RSI indicator.
Closing thoughts
In this article, weâve run through some basic examples of what you can do with TradingViewâs Pine Editor. By now, you should be confident in making simple annotations to price charts to gain additional insights from your own indicators.
Weâve only taken an interest in a couple of indicators here, but itâs easy to spin up more complex ones â either by selecting the inbuilt scripts from New or by writing them yourself.
Lacking inspiration? The following articles might provide you with some ideas for your next project: