As good as the pine script documentation is, there are still those times when things get lost in translation. Other times documentation has a specific target audience in mind. I decided to write this post after spending some time investigating the differences between “realtime” and historical data and how each type can change the calculations an indicator produces. This is especially true when you start adding the lookahead keyword. More on that later…
Note: If you are just getting started with pine script, I have a more gentle introduction here: Trading View: First Script
Historical vs Realtime Data
Realtime data should not be confused with realtime data provided by stock exchanges. In pine script realtime data is any data that arrived whilst a candle is being built (even if the data itself is delayed). Conversely, historical data refers to any candle closed before adding an indicator to the chart. Sounds logical right? Well be aware of a couple of things:
- Calculations made on realtime data can and will have different results to historical bars. This may sound obvious but you will see why this can result in undesired effects in the examples below.
- Realtime data does not become historical data once the candle is complete. In other words it is not recalculated in the same way historical data is first calculated when you add the indicator. Again, I hope the examples below will make this clear.
Lets move on with a practical example and create an indicator.
The Indicator
The indicator we will develop shall overlay daily high and low values over an intra-day chart. This might be useful if you wanted to look for breakouts above/below the high or low of the day before.
Example 1 – Vanilla
The code below is the simplest example in the post. If like me, you may choose to build the indicator this way on your first attempt. The indicator simply gathers high and low values for the same instrument using the daily timeframe. It then plots those values over the current timeframe.
1 2 3 4 5 6 7 8 |
//@version=3 study("Barmerge Tests", overlay=true) daily_high = security(tickerid, "D", high) daily_low = security(tickerid, "D", low) plot(daily_high, style=cross, color=green) plot(daily_low, style=cross, color=red) |
As usual, copy and paste the code above directly into Tradingview’s pine script editor and add the indicator to your chart.
Result 1
In the image above, the historical data is calculated and plots as expected. We have one nice straight line from the start to the end of each day. However, look what happens when the realtime data arrives. The bars shift up in the middle of the day!
After looking more closely at the lines generated after the indicator was added (realtime data), you may notice that the values have shifted to the high / low values for the current day. I hope this example highlights points 1 and 2 above.
Lookahead
Lookahead allows an indicator to look at future values in the for calculations. If we set “lookahead_on“, the indicator will look ahead to find high and low for the rest of the day. It will then use them for plotting each intra-day bar that day, no matter whether we are before or after the high or low for that day. The example below shows this in more detail.
Example 2 – lookahead on
lookahead is on in the example below. Note that if you do not give a keyword argument, the default value is off (barmerge.lookahead_off).
1 2 3 4 5 6 7 8 |
//@version=3 study("Barmerge Tests", overlay=true) daily_high = security(tickerid, "D", high, lookahead=barmerge.lookahead_on) daily_low = security(tickerid, "D", low, lookahead=barmerge.lookahead_on) plot(daily_high, style=cross, color=green) plot(daily_low, style=cross, color=red) |
Result 2
The example above had just been added to the chart. For historical data the high and the low for the day are plotted before they actually happen intra-day! You should never use this type of indicator for backtesting. For example, you could skew the results by entering a short position at the high of the day then closing before the end of the day. You would have great results but they would not be applicable in the real world.
For realtime data, the calculation is different when price moves beyond the current high and low for the day. Stating the obvious, this is because we cannot look into the future for bars that are yet to form and they could yet go higher or lower.
Below is an example of the chart using realtime data where price moves beyond the known historical high and low data.
Example 3 – lookahead on & index.
The last example combines looking ahead with an indexed data. It results in an indicator which works as expected. Perhaps counter-intuitively, when we look ahead on indexed data, we are looking ahead on the data for the day before. (which is back in the past again!)
1 2 3 4 5 6 7 8 |
//@version=3 study("Barmerge Tests", overlay=true) daily_high = security(tickerid, "D", high[1], lookahead=barmerge.lookahead_on) daily_low = security(tickerid, "D", low[1], lookahead=barmerge.lookahead_on) plot(daily_high, style=cross, color=green) plot(daily_low, style=cross, color=red) |
Result 3
Here we can see that the high and low lines show the results from the previous days’ range. Additionally realtime data provides the same value.
[…] 9 – Tradingview: Understanding lookahead, historical and realtime data […]
If we use ref data ( previous data like close[1] ), do we need to use “lookahead=barmerge.lookahead_off” ?
Thanks
Hi Fatih!
It depends on how you want the indicator to behave for realtime data?
In the last example I have it on with previous data (close[1]). If you didn’t have it on, it will plot the high and low from the day before last for historical data. When realtime data kicks in, it will plot the high / low from yesterday. This results in a jump like in example 1.
You can test this by opening up a fast moving instrument like Forex, placing it on the 1 min chart and copying the code in example 3. Remove the lookahead option and plot the indicator then take a look at the values which are plotted for historical data. Lastly, wait for the indicator to shift when the current candle ticks.
Not sure if that answers your question! Let me know if not.
Hi. My code is example this like:
version=4
a=security(renkoID,tim,open[1],lookahead = barmerge.lookahead_on)
I do backtest on tradingview. Using my code above is true? Or for the accurate backtest results which one I must use “barmerge.lookahead_on” or “barmerge.lookahead_off”. Which one is reliable for backtest results? And whichever it can, must I use [1]…[2] historical operator? Thanks for your interests.
Hi there, I noticed the barmerge options don’t apply to study, only strategy. Is there a way to workaround this?
Thank-you!
Hi Derek,
Thanks for the comment!
Sorry, can you elaborate a bit more? The examples above are using studies. What are you trying to do and with which barmerge options?
Cheers
Hi, Tx for all the help you provide with your tutorials!
I´m currently practicing on an indicator with Pivot Points and I need to figure it out how to plot the horizontal lines that I currently have but to the future!
I mean, for example, Today is Feb 8, and my monthly pivot point just shows from the 1st of Feb, until today, I can´t figure it out to plot that line until the end of Feb, 30? It’s something that it´s possible, without using the track price option on the plot?
Tx, Bruno!
Hi Bruno,
I am not sure it is possible to plot into the future without using horizontal lines. If it is possible, I have not discovered it. (which is equally possible!).
As new lines come in, your current pivot should plot in the correct position up until the next pivot. Is there a specific reason you want to plot into the future? Is it so you can get an idea of when the pivot is likely to change?
How to get next future bar for backtesting limit orders? (in the same time frame)
I have a strategy on 4 hr time frame and it works good.
When the strategy fires a long I want to know the future bar in order to experiment with limit order fills as a function of undercutting the order book with xx%
Example: If strategy fires long signal and future bar got lower wick I know it got filled, and if there is no wick it did not get filled.
Is there another way to use limit orders in strategies? am I missing the right way to do this?
Any help with this would be greatly appreciated
Is it currently possible to update the historical bars plot when the realtime data moves the current day’s high/low? It’s a pain to refresh the page every time I need updated indicator data.
Not that I am aware of… but that does not mean no!
Hey your tutorials are great and I’m really glad that you provide this kind of help.
I’ve got a question to a strategy I’m experimenting with. I got basically everything set and done, but I got a problem that i can’t seem to fix on my own. I don’t like earnings and it kind of screws the data, so the idea is that it shouldn’t buy when it’s 5 days to the earnings for example.
I’ve found this piece of code online which marks the earnings and also the time (or date) of it.
//@version=3
study(“Plot earnings”, overlay=true)
esd = input(“EARNINGS”, options=[“EARNINGS”, “DIVIDENDS”, “SPLITS”])
t = tickerid(“ESD”, syminfo.prefix + “_” + ticker + “_” + esd)
c = security(t, “D”, close, true, lookahead = barmerge.lookahead_on)
o = security(t, “D”, open, true, lookahead = barmerge.lookahead_on)
h = security(t, “D”, high, true, lookahead = barmerge.lookahead_on)
u = security(t, “D”, updatetime, true, lookahead = barmerge.lookahead_on)
plotshape(c)
plotshape(o)
plotshape(h)
plotshape(u)
// c – earning
// o – estimate
// h – date (in unix time)
// u – period ending (in unix time)
So is there a way in which i can set the strategy that it won’t go long if the pattern x occured y days before the earnings?
Thanks a lot in advance.
Jerome