Search code examples
pine-scriptpine-script-v5

Why moving average is not calculated in the IF statement in PineScript?


Why the label output is NaN in the following code?

//@version=5
indicator("My script")

if barstate.islast
    ema = ta.ema(close, 21)
    label.new(bar_index, 0, str.tostring(ema[bar_index]))

plot(close)

Solution

    1. For optimization, calculations in conditional blocks occur only when the block condition is fulfilled, and the calculated value creates a series - every time the script gets into a conditional block and counts something, it writes this value to history, thus, even if you 1000 bars, but the condition was fulfilled only for 10 of them, the history of such a variable will consist of 10 values ​​and if you call bars backs 1000 bars in the history you will get NA, since the value 1000 bars ago did not exist.
    2. In addition, functions like ema are considered with a window, in this case the window is equal to 21 bars, that is, conditionally you need to find the sum of 21 bars, if you have several calls, then summing 21 bars each time is expensive, so the previous value is subtracted and a new one is added, getting thanks to two actions, the same amount as when performing 21 additions.

    Taking into account both of these points, the calculation of the amount will occur only when a conditional block is hit, and since hits may not occur on every bar, the amount will be distorted (when calculating, the previous historical value will be subtracted, it may turn out that it was many bars ago). Therefore, such functions are more reliably called outside of conditional blocks. But if you calculate it only once on the last bar, then the second point will not create problems. Only the first one, because you do not have a historical EMA value on the first bar, because your script did not calculate the EMA on the first bar.

    It is described in official Pine manual https://www.tradingview.com/pine-script-docs/en/v5/language/Execution_model.html#historical-values-of-functions