Knowing your way around a coding language is undoubtedly a significant advantage when it comes to trading the markets. It allows traders to test trading strategies quickly, implement custom indicators, and create tailor-made systems outside the scope of any no-code alternative available in the market. You can read more about this in my article on whether algorithmic trading is worth learning or not.
Although plenty of general-purpose programming languages can also be applied to financial markets, Tradingview’s Pinescript stands out because it was designed from the ground up with the sole purpose of trading in mind. It is thus one of the most convenient scripting languages available for non-programmers that want to quickly be able to implement a custom indicator or trading idea without having to go through months of doing courses and reading books.
Last but not least, it is worth mentioning that TradingView is a rather limited tool, and you’ll probably be able to backtest more nuanced strategies using BacktestXL. This backtesting engine works natively in Microsoft Excel and also fetches historical stock prices and alternative datasets. It also calculates technical indicators and has pattern recognition functions. The most powerful feature is the parameter optimization feature, which is a one-of-a-kind in the market. Disclaimer: we’re the developers, but it really is the software we use for our personal research!
In this article, I will go through the main aspects of Pinescript, answer the most commonly asked questions, and give a step-by-step tutorial that will get you started immediately. So, without any further ado, let’s dive right into it!
Is Pinescript easy to learn?
Pinescript features a very nice learning curve, making it an excellent option for those users only interested in coding trading-related scripts. Since it is a custom scripting language created for the sole purpose of applying it to financial markets, it has numerous built-in functionalities that work right out of the box. It would require substantial coding experience to replicate in other programming languages.
Step-by-step Tradingview Pinescript Tutorial
Getting started with Pinescript
I always find it essential to know the outcome of what I’m about to learn, so here it is: by the end of this tutorial, we will have created a fully parametrizable custom indicator, which we’ll call ‘Watermark Volatility.’ It is supposed to provide information regarding a given asset’s recent volatility.
I’ll still mention that this indicator is created only for teaching purposes, and I have allocated precisely 0 minutes to testing whether it is useful for trading or not.
In the following tutorial, I’ll assume that you already know your way around Tradingview and that you want to go straight to learning the basics of Pinescript by means of an example. I always found it easier to learn a new skill by following a tutorial instead of looking at the documentation or a user manual.
To get started coding, click on the ‘Pine Editor’ button on the bottom ribbon of your Tradingview session (see screenshot below).
We will see the following lines of code:
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © martinnmayer //@version=5 indicator("My script") plot(close)
The first two lines are examples of comments. These start with two forward slashes, which tell the Pinescript interpreter to ignore those lines. In other words, comment lines are just for humans and are very useful for explaining and detailing the rationale behind lines of code that could be difficult to understand.
The first line that is not a comment tells TradingView that we are creating an indicator, and between the parenthesis, we indicate the indicator’s name.
Last but not least, ‘plot(close)’ indicates that we want to plot the close of each bar on the TradingView. You can go ahead and save the script and click on “Add to Chart.” If you minimize the Pinescript editor, you will see that you can now also visit our newly created “indicator.” At the time being, it is nothing short of underwhelming.
Before moving on to a more interesting use case of Pinescript, you’ll notice that the indicator is plotted below the main chart and not on top. In some cases, this might be the desired outcome, but in this specific situation, it would make more sense to display the indicator on top of the candles. To do so, go ahead and add the following parameter to the declaration of the indicator:
indicator("My script", overlay = true)
Creating a custom indicator in Pinescript
In this tutorial, we will create a custom indicator that will display the high watermark of the price of an asset during the past N bars. As you might already know, every bar has an open, high, low, and closing value. A common mistake, in this case, would be to use the closing price when we require the high of each bar to calculate the maximum correctly.
Now, let’s start by declaring a variable as the highest price over the last 24 bars:
high_water_mark = ta.highest(high, 24)
Let’s go ahead and break this down. We declared a variable and called it “high_water_mark.” Every line of code that follows that one will have access to that variable, and thus we could be able to use it as input for another variable or even to update its definition. On the right hand, we specify the value of the variable declared.
Pinescript already has a lot of built-in functions available, and some of them are declared within the ‘ta’ namespace, which stands for “technical analysis.
Instead of creating the logic of calculating the highest price, we can use the ‘highest’ function. This function only requires two parameters: the series that we will use to calculate and how many bars back we want to go. In this case, we are using the ‘high’ series and going back 24 bars. A very helpful feature of Pinescript‘s IDE (Integrated Development Environment) is its documentation. If you hover the mouse over a function, it will show a brief description of what it is supposed to do, in addition to listing the inputs that it requires:
If you were paying attention, you’d notice that in the previous example, we plotted the ‘close,’ and now we’re using the ‘high.’ If you think that you can also access the open and the low in a similar fashion, you’re exactly right!
If we now replace ‘plot(close)’ with ‘plot(high_water_mark)’ and save the script, we’ll be able to see the watermark of the last 24 periods in the chart.
It would also be nice to go ahead and add the lowest prices featured in the lookback period. Even though it would not make any sense whatsoever in the physical realm, let’s call it “low_water_mark.” If you’ve been obedient, your code will look as follows:
indicator("Watermarks", overlay = true) high_water_mark = ta.highest(high, 24) low_water_mark = ta.lowest(low, 24) plot(low_water_mark) plot(high_water_mark)
Of course, we’re using each candle’s low instead of the high in this new code addition. I also went ahead and renamed the indicator.
Let’s do something more interesting (maybe even somewhat helpful). Dividing the high_water_mark by the low_water_mark might be interesting for analyzing a stock’s current volatility.
This indicator, although simple, yields important information regarding the current volatility of an asset’s price. If both lookback periods match, the Watermarks indicator’s value will always be greater than or equal to 1 since the high_water_mark cannot be smaller than the low_water_mark for the same period.
Last but not least, and to wrap this tutorial up, we might be interested in adding some bells and whistles to our novel indicator. If you’ve been using Tradingview for some time or any other charting tool worth its salt, you might have noticed that it is almost always possible to define the parameters of an indicator. In this case, it would be nice to specify each watermark’s lookback period. This can be done by adding inputs to our Pinescript code:
//DEFINE THE INDICATOR AND NAME IT indicator("Watermark Volatility") //CALCULATE THE HIGH WATERMARK BASED ON USER INPUT VALUE high_loockback = input.int(title="High Watermark Loockback", defval=24, minval=1) high_water_mark = ta.highest(high, high_loockback) //CALCULATE THE LOW WATERMARK BASED ON USER INPUT VALUE low_loockback = input.int(title="Low Watermark Loockback", defval=24, minval=1) low_water_mark = ta.lowest(low, low_loockback) // CALCULATE THE INDICATOR water_volatility = high_water_mark / low_water_mark p1 = plot(water_volatility,color=color.red,linewidth = 5, title='Watermark Volatility') p2 = plot(1) fill(p1,p2)
You’ll quickly notice a few extra lines of code. There are two additional variables, called high_loockback and low_loockback, respectively. This will allow the end user to manually set the desired value instead of forcing the preset value of 24 that we previously used. For this, we use the int type input (integer), which is (roughly) a fancy term for describing whole numbers in computer science. We still set the default value to 24 and force the value to be equal to or greater than 1 (0 or negative values would not make any sense in this case).
Also, instead of plotting the indicator, we assign the result to a variable called ‘p1’. I also went ahead and added a few additional parameters to the plot function that are pretty self-explanatory. We also define an additional plot, which is none other than a horizontal line at 1. We use the ‘fill’ function and pass both plots as arguments. The fill function will plot the difference between p1 and p2. If you save the script and switch back to the charting view, you’ll see the following:
More interestingly, you will also be able to parametrize the values of the watermarks without having to modify the script and save it.
Frequently Asked Questions
Can you create Machine Learning algorithms in Pinescript?
Pinescript is not a suitable scripting language for statistical, econometric, or machine-learning applications. Because it has no inherent numerical methods or optimization libraries, it does not have the capacity to train machine learning models.
It is entirely possible to train a machine learning model using another programming language or third-party software (it could even be Ms. Excel), and use the resulting parameter values in Pinescript.
Is Pinescript similar to Python?
Pinescript and Python have some similarities when it comes to their syntax. Having said that, Python is a high-level, general-purpose programming language that can be used in a much broader array of cases. It is widely used in data science, machine learning, game development, and even for creating websites, in addition to algorithmic trading. Pinescript, on the other hand, is only intended to be used for trading purposes within the Tradingview ecosystem.
What are the limitations of Pinescript?
Due to its ease of use, Pinescript also has a few limitations and is thus unsuitable for a few use cases. For example, if you plan on using tick-level data and implementing a market-making strategy, Pinescript (and thus Tradingview) won’t allow you to do so.
Additionally, it is a somewhat limited tool for applying statistical models and has no built-in functionalities for training machine learning models.
It is also worth mentioning that Tradingview and Pinescript are not suitable for implementing trading strategies based on alternative data, such as news events, satellite images, or credit card transactions, amongst many others, since it only allows to use of OHLCV data.
Last but not least, since Tradingview is a web app, it uses cloud resources for computing calculations. Thus, Tradingview imposes different limitations based on the type of plan you are subscribed to.
Is Pinescript Open-Source?
Pinescript is a proprietary and closed-source scripting language developed and maintained by TradingView Inc. Thus, its source code is unavailable to the public. It is not possible to use Pinescript locally on your computer, and it can only be used within the confinements of the Tradingview platform.