The new varip keyword in Pine can be used to declare variables that escape the rollback process, which is explained in the Pine User Manual's page on the execution model. This publication explains how Pine coders can use variables declared with varip to implement logic that was impossible to code in Pine before, such as timing events during the realtime bar, or keeping track of sequences of events that occur during successive realtime updates. We present code that allows you to calculate for how much time a given condition is true during a realtime bar, and show how this can be used to generate alerts.
█ WARNINGS
1. varip is an advanced feature which should only be used by coders already familiar with Pine's execution model and bar states. 2. Because varip only affects the behavior of your code in the realtime bar, it follows that backtest results on strategies built using logic based on varip will be meaningless, as varip behavior cannot be simulated on historical bars. This also entails that plots on historical bars will not be able to reproduce the script's behavior in realtime. 3. Authors publishing scripts that behave differently in realtime and on historical bars should imperatively explain this to traders.
█ CONCEPTS
Escaping the rollback process Whereas scripts only execute once at the close of historical bars, when a script is running in realtime, it executes every time the chart's feed detects a price or volume update. At every realtime update, Pine's runtime normally resets the values of a script's variables to their last committed value, i.e., the value they held when the previous bar closed. This is generally handy, as each realtime script execution starts from a known state, which simplifies script logic.
Sometimes, however, script logic requires code to be able to save states between different executions in the realtime bar. Declaring variables with varip now makes that possible. The "ip" in varip stands for "intrabar persist".
Let's look at the following code, which does not use varip:
On historical bars, barstate.isnew is always true, so the plot shows a value of "1". On realtime bars, barstate.isnew is only true when the script first executes on the bar's opening. The plot will then briefly display "1" until subsequent executions occur. On the next executions during the realtime bar, the second branch of the if statement is executed because barstate.isnew is no longer true. Since `updateNo` is initialized to `na` at each execution, the `updateNo + 1` expression yields `na`, so nothing is plotted on further realtime executions of the script.
If we now use varip to declare the `updateNo` variable, the script behaves very differently:
The difference now is that `updateNo` tracks the number of realtime updates that occur on each realtime bar. This can happen because the varip declaration allows the value of `updateNo` to be preserved between realtime updates; it is no longer rolled back at each realtime execution of the script. The test on barstate.isnew allows us to reset the update count when a new realtime bar comes in.
█ OUR SCRIPT
Let's move on to our script. It has three parts: — Part 1 demonstrates how to generate alerts on timed conditions. — Part 2 calculates the average of realtime update prices using a varip array. — Part 3 presents a function to calculate the up/down/neutral volume by looking at price and volume variations between realtime bar updates.
Something we could not do in Pine before varip was to time the duration for which a condition is continuously true in the realtime bar. This was not possible because we could not save the beginning time of the first occurrence of the true condition.
One use case for this is a strategy where the system modeler wants to exit before the end of the realtime bar, but only if the exit condition occurs for a specific amount of time. One can thus design a strategy running on a 1H timeframe but able to exit if the exit condition persists for 15 minutes, for example. REMINDER: Using such logic in strategies will make backtesting their complete logic impossible, and backtest results useless, as historical behavior will not match the strategy's behavior in realtime, just as using `calc_on_every_tick = true` will do. Using `calc_on_every_tick = true` is necessary, by the way, when using varip in a strategy, as you want the strategy to run like a study in realtime, i.e., executing on each price or volume update.
Our script presents an `f_secondsSince(_cond, _resetCond)` function to calculate the time for which a condition is continuously true during, or even across multiple realtime bars. It only works in realtime. The abundant comments in the script hopefully provide enough information to understand the details of what it's doing. If you have questions, feel free to ask in the Comments section.
Features The script's inputs allow you to: • Specify the number of seconds the tested conditions must last before an alert is triggered (the default is 20 seconds). • Determine if you want the duration to reset on new realtime bars. • Require the direction of alerts (up or down) to alternate, which minimizes the number of alerts the script generates. The inputs showcase the new `tooltip` parameter, which allows additional information to be displayed for each input by hovering over the "i" icon next to it.
The script only displays useful information on realtime bars. This information includes: • The MA against which the current price is compared to determine the bull or bear conditions. • A dash which prints on the chart when the bull or bear condition is true. • An up or down triangle that prints when an alert is generated. The triangle will only appear on the update where the alert is triggered, and unless that happens to be on the last execution of the realtime bar, it will not persist on the chart. • The log of all triggered alerts to the right of the realtime bar. • A gray square on top of the elapsed realtime bars where one or more alerts were generated. The square's tooltip displays the alert log for that bar. • A yellow dot corresponding to the average price of all realtime bar updates, which is calculated using a varip array in "Part 2" of the script. • Various key values in the Data Window for each parts of the script. Note that the directional volume information calculated in Part 3 of the script is not plotted on the chart—only in the Data Window.
Using the script You can try running the script on an open market with a 30sec timeframe. Because the default settings reset the duration on new realtime bars and require a 20 second delay, a reasonable amount of alerts will trigger.
Creating an alert on the script You can create a script alert on the script. Keep in mind that when you create an alert from this script, the duration calculated by the instance of the script running the alert will not necessarily match that of the instance running on your chart, as both started their calculations at different times. Note that we use alert.freq_all in our alert() calls, so that alerts will trigger on all instances where the associated condition is met. If your alert is being paused because it reaches the maximum of 15 triggers in 3 minutes, you can configure the script's inputs so that up/down alerts must alternate. Also keep in mind that alerts run a distinct instance of your script on different servers, so discrepancies between the behavior of scripts running on charts and alerts can occur, especially if they trigger very often.
Challenges Events detected in realtime using variables declared with varip can be transient and not leave visible traces at the close of the realtime bar, as is the case with our script, which can trigger multiple alerts during the same realtime bar, when the script's inputs allow for this. In such cases, elapsed realtime bars will be of no use in detecting past realtime bar events unless dedicated code is used to save traces of events, as we do with our alert log in this script, which we display as a tooltip on elapsed realtime bars.
█ NOTES
Realtime updates We have no control over when realtime updates occur. A realtime bar can open, and then no realtime updates can occur until the open of the next realtime bar. The time between updates can vary considerably.
Past values There is no mechanism to refer to past values of a varip variable across realtime executions in the same bar. Using the history-referencing operator will, as usual, return the variable's committed value on previous bars. If you want to preserve past values of a varip variable, they must be saved in other variables or in an array.
Resetting variables Because varip variables not only preserve their values across realtime updates, but also across bars, you will typically need to plan conditions that will at some point reset their values to a known state. Testing on barstate.isnew, as we do, is a good way to achieve that.
Repainting The fact that a script uses varip does not make it necessarily repainting. A script could conceivably use varip to calculate values saved when the realtime bar closes, and then use confirmed values of those calculations from the previous bar to trigger alerts or display plots, avoiding repaint.
timenow resolution Although the variable is expressed in milliseconds it has an actual resolution of seconds, so it only increments in multiples of 1000 milliseconds.
Warn script users When using varip to implement logic that cannot be replicated on historical bars, it's really important to explain this to traders in published script descriptions, even if you publish open-source. Remember that most TradingViewers do not know Pine.
New Pine features used in this script This script uses three new Pine features: • varip • The `tooltip` parameter in input(). • The new += assignment operator. See these also: -=, *=, /= and %=.