I recently received a question regarding indicator repainting in Tradingview and quickly came to realize that it would make a great topic for a post. If you don’t understand it correctly, repainting can lead to confusion, unrealistic expectations and a belief that there are bugs in the script or pine script language itself. For such an important topic, there is a surprising lack of documentation in the Tradingview wiki.
As of today, if I type “Tradingview repainting” into google, the first result which comes up is a link to the Tradingview wiki. It is a page dedicated to the topic. Unfortunately, it only contains a few (worrying) lines!
Pine Script is a programming language that is designed for custom indicators development on TradingView. This is vector-based programming language, engineered specifically to solve problems in the field of technical analysis(See: Introduction). Despite the vast capabilities of the Pine Script programming language, the potential is not yet realised due to an error in the execution terminal that distorts and erases plotted indicators that resulted in losing trades during the backtesting process. This is referred to as Indicator Repainting.
Wow! An error in the execution terminal that distorts and erases plotted indicators that resulted in losing trades during the backtest process!! Not only is that an overly complex way of stating the problem but if that is the first thing you read on the topic, I would not be surprised if you never touched a backtest on Tradingview again. After all, who would trust a system which is losing trades? It goes against everything you are trying to achieve.
Fear not. As badly worded as that is, it may not be all doom and gloom. First, let’s take a very simple look at what indicator repainting is traditionally known as. Then we will look at how Indicator repainting can affect your results. Finally, we will discuss if it is something you should be worried about.
In its simplest form, indicator repainting happens to all indicators which rely on the close price of a candle for their calculation. During live trading or forward testing, the close value of the current bar is constantly changing from as soon as the bar opens until the moment it closes. The final close price is not known until right at the end of the bar. This means that the indicator is constantly “repainting” during the bar. You will see that indicators are constantly moving with each tick received. Place an RSI on your and watch it move to see it in action. Since the indicator moves before the candle closes, it can lead to false signals.
Conversely, in backtesting, we receive open, high, low and close data all at the same time. As such, we miss all the noise that happened during the bar. We don’t see how many times price bounced between the high and low. We also do not see how many times an indicator fired off a false signal. Therefore, in backtesting we only get a confirmed signal. The trade-off with this is that you have to wait until the open of the next bar to place an order.
How can it affect you?
Generally speaking, In a pure backtest environment it will not! This is because you never had anything but historical bars of data. It may only start to affect you once you start forward testing or working on multiple timeframes.
When your strategy progresses to a forward test environment, there are some things to be aware of. First of all, in pinescript, there is a fundamental difference between how strategies and indicators work “out of the box”. A strategy will always wait for a bar to close before doing any calculations. Even when forward testing. This ensures that your forward test results behave in a similar manner to your backtest results. The chart below shows the difference between a strategy and an indicator. The chart price data was hidden and two sets of moving averages with the same values. One set of MA’s are from a strategy, the other set are from an indicator. You can see that the indicator lines extend out and update in real-time with the live data. You might need to squint to see the difference! The strategy MA’s are a little thicker and darker in color.
Having said that, if you do want the strategy to repaint, an option is available. Check the re-calculate on every tick box in the strategies properties. (You can also set this progmatically). The strategy will update in the same fashion as an indicator. Entries and exits will happen on the tick of new data. This can result in multiple entries and exits during a bar which would not be seen during a backtest. Lets take a look (click on the pictures to enlarge them):
This is a classic example which shows why trades can disappear. It also shows why entering on the tick can be dangerous. In the first image, you can see we have a moving average crossover signal occurring before the bar closes. As a result, a short entry is created. However, when you look at the same chart on the following bar, you can see that the crossover was never confirmed. Price reversed and at the close, the moving averages are no longer crossed. If you run the same script on historical data, this trade would have never happened. This is why users can easily report that their trades disappeared. Especially, if they refresh the page as everything is reloaded and that bar is now historical data.
As mentioned in the “why are my trades delayed?” post, when you take entries before a bar is closed, you are no longer trading price action on the time-frame you are working on. There are times when you might want to do this but in general, I do not recommend it as your backtest results will not be indicative of your forward test results.
There are two potential issues that can affect repainting when we start to use upper timeframe data in our strategies.
- Accidentally using data from the future.
- Sampling the upper timeframe data before the upper timeframe candle has closed.
Both of these issues can cause repainting issues. This article addresses issues that can arise from accidentally using future data. A second article: Tradingview: Strategy Forward Testing & Upper Timeframe Repainting Fix addresses sampling issues. The topic is too large to fit into this article and deserved a dedicate post where we can dive deeper.
Tradingview did have an issue in version 2 of pine script whereby if you were working on dual time-frames, you would receive complete open, high, low and close data for the higher time-frame on the first bar of the lower time-frame. If that boggles your mind, think about it this way. Let’s imagine we are working on hourly and daily time-frames. Our imaginary day is over and is closed as:
- Open 10, High 20, Low 5, Close 15.
Later we decide to backtest the data from our imaginary day using the daily and hourly time-frames. On the first bar of the day we would receive the first hourly bar along with the complete values for the daily bar. This would continue and we would receive the same daily data on every bar from the 1st to the 24th bar like so:
- Bar 1: Hourly Data: Open 10, High 11, Low 9, Close 9.5
- Bar 1: Daily Data: Open 10, High 20, Low 5, Close 15.
- Bar 2: Hourly Data: Open 9.5, High 10, Low 7, Close 8.5
- Bar 2: Daily Data: Open 10, High 20, Low 5, Close 15.
- ….and so on for 24 bars
Well. that would be great if we just want to look like a market wizard. We already have the high of the day, before the end of the day! We have future data. Using this, we could just set a take-profit for the high of the day and have a 100% win rate. Obviously, this is a major flaw from a backtest perspective as you would never have access to the high of the day during the first hour.
At this point, I should note that this “flaw/issue” is not actually an issue per se. There are use cases for indicators where having access to these values is useful and we must remember that indicator development is an equally important aspect of pine script.
Having said that, version 3 of pine script addresses the issue. There is now a parameter which can be set when requesting data. The parameter is
lookahead. As the name suggests you can look ahead and be given the data for the full period even if it has not closed yet on the lower time frame. It should be noted that this is off by default.If you are working on a strategy, it would be madness to turn it on.
Let’s take a look at an example.
The example above shows a strategy which enters a long or short position at the high of the day. Using real-time data you can see that a position is created every time a new high or low is made. If you had lookahead turned on and refreshed the page, the indicator will repaint and trades are lost. More importantly, the results are not realistic. The backtest results are flawed for the reasons outlined above.
Tradingview and Pine script are still relatively new in the grand scheme of things. Therefore, we should expect to find the odd bug here or there. However, in my opinion, repainting has been appropriately addressed in version 3 of pine-script and should not pose a problem from a backtest perspective. Having said that, I would love to hear any alternative views on this topic or examples that might change my mind. If you have an opposing view, let me know (politely) in the comments below and we can have a healthy discussion.
Support the site
If you like this article and are thinking to become a Tradingview subscriber, you can support the site by clicking on the affiliate link below before signing up!