Warning: Declaration of ElementorPro\Modules\Posts\Skins\Skin_Content_Base::register_controls(Elementor\Widget_Base $widget) should be compatible with Elementor\Controls_Stack::register_controls() in /home/customer/www/backtest-rookies.com/public_html/wp-content/plugins/elementor-pro/modules/theme-builder/widgets/post-content.php on line 17
Today’s post comes courtesy of a request from one of the blog’s readers. Arun got in touched and asked for some help with the following:
Please explain what highestbars() and lowestbars() functions in
Tradingview does with some examples.
They seem to plot some interesting lines, but I don’t see any script using it.
After looking into this, I can understand why Arun might be a bit baffled for use cases. So let’s take a look at the functions, their output and what they could potentially be used for.
highestbars() and lowestbars()
In a nutshell, these two functions simply return the number of bars since the
highest high or
lowest low within a given time period. The number is returned as a negative number and as such, is intended to be used as an offset.
Here is an excerpt of
highestbars()from the official docs:
highestbars Highest value offset for a given number of bars back. highestbars(source, length) → series[integer] highestbars(length) → series[integer] RETURNS Offset to the highest bars
Since offsets are only used for plotting, the original intention for these functions was probably for use with one of the many
plot() functions. Furthermore, we can rule out indexing as the primary use case because if you try indexing with a negative number, you will receive an error for your efforts. However, as with any tool, we can be creative and use it in areas for which it was not originally intended. For example, we will actually still use it for indexing in one of the code snippets below by making the output a positive value.
Having said all that, let’s start with the basics:
Note: Throughout these examples only
highestbars() will be used.
lowestbars()works in exactly the same way but as mentioned above, it just counts from the
Plotting the output
We will begin with simply plotting the output from the indicator to get a feel for the values it produces.
//@version=3 study("RSI Highestbars") rsi = rsi(close, 14) hb = highestbars(rsi, 20) plot(hb, color=purple)
In the code snippet above we are returning the bar offset to the highest
RSI value in the last 20 bars. This highlights one potential area for creativity. That is, you don’t need to use this simply with price data from the candlestick chart. Try putting different data
series in here as a source.
When we run the code, you will notice a few things:
Use case one: Plotting
Now we understand how the basic output works, we can move onto exploring different use cases and there is no better place to start than that for which the function was intended! In this example we with use the
offset in conjunction with
show_last to highlight the most recent high on the chart. Using
show_lastwill mean that the highlight will move as the most recent high moves.
//@version=3 study("Highestbars - Use Case 1") rsi = rsi(close, 7) hb = highestbars(rsi, 20) plot(rsi) // Show most recent high bgcolor(red, offset=hb, show_last=1, title='Most Recent High')
As we can see when the code is plotted, the most recent high of the RSI is highlighted with a red background:
Use Case Two: Looping
Our second use case is a bit different. Here we are going to use the output to loop through and analyze all the bars since the
highest highto make a trading decision. As we loop through we are going to make a count of all bullish and all bearish bars on the chart.
//@version=3 study("Highest Bars - Use Case Two") rsi = rsi(close, 7) hb = highestbars(rsi, 20) plot(rsi) redbars = 0 greenbars = 0 // need to use minus '-' to covert to positive number for i = 0 to -hb greenbars:= close[i] > open[i] ? greenbars + 1 : greenbars redbars:= close[i] < open[i] ? redbars + 1 : redbars plot(redbars, style=columns, color=red, transp=70) plot(greenbars, style=columns, color=green, transp=70)
This example is a little more complex. In it, we need to change returned value from
highestbars() to an absolute value. I.e switch it from negative to positive. Only then can we index correctly. To do this we can use the
abs() function or as in the example, place a
-sign in front of the variable to flip it. From here we simply loop through the range counting whether the bar closed up or down.
When placed on the charts you should see something like this:
Use Case Three: Retracements
In the final example, we are going to use
highestbars()to calculate how far price has retraced from the most recent high. This could be useful for triggering entries right on some Fibonacci levels.
In my blog posts, I often use the saying “there is more than one way to skin a cat” and this example proves just that. The example can be fully replicated using the
highest() function too. It is just one of those cases where there is no correct answer. The main thing is to use the tools you feel comfortable with that allow you to meet your target.
//@version=3 study("Highest Bars - Use Case Three") rsi = rsi(close, 7) hb = highestbars(rsi, 20) plot(rsi) // Show Percentage Retracement since Highest Bar // Note it will always be 0 or below because we are measuring from the highest // point. diff = ((rsi - rsi[-hb]) / rsi[-hb]) * 100 plot(diff, color=black, title='RSI Retracment') // Note we can also do this with higest() diff_alt = ((rsi - highest(rsi, 20)) / highest(rsi, 20) ) * 100 plot(diff_alt, color=black, title='RSI Retracment - Highest()')
As we can see in the code, examples have been given using both
highest(). You will notice that when it is plotted, the two lines produce exactly the same value.
Note: In the image above, the retracement line is always zero or below. This is because we can never be above the highest high!
Find This Post Useful?
If this post saved you time and effort, please consider support the site! There are many ways to support us and some won’t even cost you a penny.