Pine Script v6 missing data

Pine Script na/nz: Missing Data vs Zero

In Pine Script, na means a value is unavailable. na(x) detects it; nz(x, replacement) substitutes a value only when x is na. For numbers, nz(x) defaults to zero. Choose the replacement from the calculation: an empty running total can start at zero, but an unknown price is not a zero price.

Review Missing Data with AI

na(), nz(), and v6 type limits

Use na(x) to test availability. Direct comparisons such as x == na are invalid. nz() accepts int, float, and color values, but not strings or booleans. The replacement must be compatible with the selected overload; it may itself be a series.

OperationMeaningConstraint
na(x)True when x is unavailableNot a bool argument in v6
nz(x)Preserves x unless it is naNumeric default: 0 or 0.0; color default: transparent black
nz(x, replacement)Uses replacement when x is naIf both are na, the result stays na
float level = naDeclares an unavailable floatA bare level = na has no inferable type

First-bar example: missing history is not a zero price

Assume three synthetic prices: 100, 103, and 101. On bar 0, there is no preceding observation. The table compares a raw difference, a zero price fallback, and an explicit convention that the initial difference is zero. These are demonstration inputs, not market results.

  • A rule that triggers when the difference exceeds 5 would fire on the first bar after a zero price fallback. The observed sequence provides no previous price to support that signal.
  • Using the current price as the fallback makes the first difference zero by convention. If the rule requires an observed previous price, keep the difference na and wait instead.
Bar / pricePrevious priceRaw differencePrevious price filled with 0Initial difference set to 0
0 / 100nana100 − 0 = 100100 − 100 = 0
1 / 103100333
2 / 101103−2−2−2

Run the same demonstration in Pine Script v6

Paste this indicator into the Pine Editor. Its synthetic price is 100 on bar 0, 103 on bar 1, and 101 thereafter, independently of the chart symbol. Inspect the first three dataset bars in the Data Window and compare them with the table. The plots expose both the unwanted zero-price result and the chosen initialization.

Synthetic data demonstration: missing history, fallback, and cumulative statepinescript
//@version=6
indicator("na and nz: synthetic first-bar demo", overlay = false)

// Demonstration prices, not market data.
float demoPrice = bar_index == 0 ? 100.0 : bar_index == 1 ? 103.0 : 101.0
float previousPrice = demoPrice[1]
float rawDelta = demoPrice - previousPrice
float zeroPriceDelta = demoPrice - nz(previousPrice)
// Explicit convention: the initial change contributes zero.
float initializedDelta = demoPrice - nz(previousPrice, demoPrice)

var float contaminatedTotal = 0.0
contaminatedTotal := contaminatedTotal + rawDelta
var float initializedTotal = na
initializedTotal := nz(initializedTotal, 0.0) + initializedDelta

plot(demoPrice, "Synthetic price", display = display.data_window)
plot(rawDelta, "Raw difference", color = color.gray, style = plot.style_linebr)
plot(zeroPriceDelta, "Zero-price fallback difference", color = color.orange)
plot(initializedDelta, "Initialized difference", color = color.blue)
plot(contaminatedTotal, "Contaminated total", display = display.data_window)
plot(initializedTotal, "Initialized total", color = color.green)
plot(na(previousPrice) ? 1 : 0, "Previous price missing (1=yes)", display = display.data_window)

Why one missing value can persist in a running total

Arithmetic with an na operand produces na. In the example, contaminatedTotal starts at 0, then adds the missing first difference. It becomes na on bar 0 and remains na when later differences are added. This is an unavailable result propagating through state; it does not itself mean the script crashed. A fresh per-bar calculation can recover as soon as its inputs exist.

  • var keeps the accumulated state across bars; := updates it. The initialized total starts as an explicitly typed float and uses zero only as its empty accumulator value.
  • Filling a contaminated total with zero only at plot time hides the missing result. It does not repair the stored total that the next bar reads.
BarContaminated totalInitialized total
00 + na = na0 + 0 = 0
1na + 3 = na0 + 3 = 3
2na + (−2) = na3 + (−2) = 1

Choose a policy for each missing input

Trace the first missing input before adding a fallback. Record whether it means insufficient history, a data gap, or a level that has not been set. Then decide whether the operation should wait, use a documented initial value, or retain a previous observation.

  • Warmup: wait for the required indicator output before using it in a signal. Substituting the current price changes the indicator definition during that interval.
  • Order levels: an unavailable stop or entry level needs a readiness check. Replacing it with zero or the current close silently creates a different order instruction.
  • Ratios: check both availability and a nonzero denominator. nz() leaves an existing zero untouched, so it is not a division-by-zero check.
  • Repeated gaps: nz(source, source[1]) looks back only one bar. Two adjacent missing observations still leave na. fixnan() uses the last non-na observation, but cannot supply a value before one exists; carrying old data also makes it stale.
Where Pineify fits

Pine Script AI Coding Agent

Bring the expression that first becomes na, the expected initialization, and a few example bars to Pineify. Ask the coding agent to trace the dependency and revise the fallback. Review the changed assumptions in TradingView before using the result in a strategy.

Review Missing Data with AI

Frequently asked questions

The example demonstrates language behavior with synthetic prices. It is not a trading strategy or evidence of performance. A replacement value cannot recover missing market observations. Pineify is independent of TradingView.

Sources and verification