Skip to content

How to get the standard deviation from a TradingView Pine Script array?

How to get the standard deviation from a TradingView Pine Script array?

Section titled “How to get the standard deviation from a TradingView Pine Script array?”

TL;DR
Keep data in a float array, ensure it has at least two elements, and use array.stdev(myArray) to measure dispersion for any custom sample set.

DifficultyBeginner
Time to implement10-15 min
CategoryArrays
//@version=5
indicator("Array stdev demo", overlay=false)
var float[] samples = array.new_float()
if barstate.isnew
array.unshift(samples, close)
if array.size(samples) > 30
array.pop(samples)
float sampleStdev = na
if array.size(samples) > 1
sampleStdev := array.stdev(samples)
plot(sampleStdev, "Sample stdev", color=color.new(color.orange, 0))
Tip. Standard deviation requires at least two elements. Guard with `array.size(arr) > 1` before calling `array.stdev()` to avoid runtime errors.

Built-in indicators like ta.stdev() operate on chart series. Arrays let you feed in anything—custom swing measurements, session returns, latency samples—and array.stdev() reports how dispersed that custom data is. That dispersion can drive regime detection, adaptive thresholds, or quality-control checks.

  • Persist arrays with var so values accumulate across bars.
  • Maintain a rolling window while keeping array size in check.
  • Combine array.avg() and array.stdev() to track both centre and spread.
  • Visualise and alert on volatility bursts captured from bespoke datasets.
CallPurpose
array.new_float()Builds a float array to hold samples.
array.unshift(id, value)Inserts the newest value at the front of the array.
array.pop(id)Removes the oldest element to keep the window bounded.
array.avg(id)Returns the mean of the array elements.
array.stdev(id)Returns the sample standard deviation of the array elements.
  1. Persist and bound the array
    Declare with var and enforce a maximum size each bar.

    var float[] buffer = array.new_float()
    array.unshift(buffer, close)
    if array.size(buffer) > 50
    array.pop(buffer)
  2. Compute the statistics safely
    Only call the statistics functions when enough samples exist.

    float mean = na
    float stdev = na
    if array.size(buffer) > 1
    mean := array.avg(buffer)
    stdev := array.stdev(buffer)
  3. Use the dispersion insight
    Plot, alert, or adjust logic when volatility shifts.

    plot(stdev, "Dispersion", color=color.new(color.teal, 0))
    if not na(stdev) and stdev > mean * 0.02
    alert("Array dispersion above threshold")
//@version=5
indicator("Session range quality", overlay=false, max_labels_count=500)
window = input.int(20, "Rolling sessions", minval=2)
threshMult = input.float(1.5, "Std dev multiplier", minval=0.1, step=0.1)
var float[] ranges = array.new_float()
sessionOpen = request.security(syminfo.tickerid, "D", open)
sessionClose = request.security(syminfo.tickerid, "D", close)
sessionRange = math.abs(sessionClose - sessionOpen)
if barstate.isconfirmed
array.unshift(ranges, sessionRange)
if array.size(ranges) > window
array.pop(ranges)
float avgRange = na
float stdevRange = na
if array.size(ranges) > 1
avgRange := array.avg(ranges)
stdevRange := array.stdev(ranges)
plot(avgRange, "Average range", color=color.new(color.blue, 0))
plot(stdevRange, "Std dev range", color=color.new(color.orange, 0))
plot(avgRange + stdevRange * threshMult, "High-volatility band", color=color.new(color.red, 40), style=plot.style_circles)
isExtreme = not na(stdevRange) and sessionRange > avgRange + stdevRange * threshMult
if isExtreme
label.new(bar_index, sessionRange,
"Extreme session\nRange: " + str.tostring(sessionRange, format.mintick),
textcolor=color.white,
bgcolor=color.new(color.red, 65))
Why this works.
  • The array holds session ranges independent of intraday timeframe.
  • `array.avg()` and `array.stdev()` track both central tendency and spread.
  • Labels and thresholds highlight when a session moves beyond its normal volatility envelope.
  • array.stdev() returns the sample standard deviation (dividing by n - 1). If you need population deviation, adjust manually.
  • Arrays consume memory; keep windows tight (20–200 elements) for real-time responsiveness.
  • Mix and match with other array functions (array.percentile, array.sort) when profiling distributions.
  • Reset arrays (e.g., on session change) by assigning a new array or calling array.clear() if you need segment-by-segment stats.

I get “Cannot call array.stdev with an empty array”

Section titled “I get “Cannot call array.stdev with an empty array””

Insert at least two values before calling the function, or guard with a size check. Empty arrays cannot form variance.

na propagates if you insert na into the array. Filter out invalid numbers before pushing them into the buffer.

Yes—push any numeric value into the array. For example, store high - low for custom ranges or strategy.closedtrades.profit(size) for trade-level stats.

  • Arrays make it easy to compute statistics on bespoke data sets beyond built-in series.
  • Guard array.stdev() with a size check and keep the array bounded for performance.
  • Pair standard deviation with the average to flag abnormal readings quickly.
  • Use labels, alerts, or adaptive logic to act on volatility information immediately.

Adapted from tradingcode.net, optimised for Algo Trade Analytics users.