Pine Script for Loop: Syntax, Lookbacks, and Array Iteration

March 17, 2026

Pine Script for Loop: Syntax, Lookbacks, and Array Iteration

March 17, 2026

Pine Script's for loop is the primary tool for performing lookback calculations, iterating over arrays, and implementing custom indicators that built-in functions can't express. The syntax is different from Bash or Python, there are a few gotchas (the end value is inclusive, you can't break out early), and performance limits apply. This guide covers everything you need to write effective for loops in Pine Script.

for i = 0 to length - 1 iterator start keyword end (inclusive) for [val, idx] in myArray — array iteration syntax (Pine Script v5)
Pine Script for loop anatomy — the end value is inclusive (unlike most languages)

1. Basic For Loop Syntax

pine
//@version=5
indicator("For Loop Demo", overlay=false)

// Basic: for i = start to end  (end value is INCLUSIVE)
// This loops i = 0, 1, 2, 3, 4 (5 iterations)
sumVal = 0.0
for i = 0 to 4
    sumVal += close[i]   // close[0]=current, close[1]=1 bar ago, etc.
plot(sumVal / 5, "5-bar sum / 5")

// With step parameter: by step (default step is 1)
evenSum = 0.0
for i = 0 to 10 by 2   // i = 0, 2, 4, 6, 8, 10
    evenSum += i
// evenSum = 30

// Countdown
for i = 9 to 0 by -1   // i = 9, 8, 7, ..., 0
    // process i

2. The Inclusive End Gotcha

In most languages, for i = 0 to N runs N iterations (0 through N-1). In Pine Script, the end is inclusivefor i = 0 to 9 runs 10 iterations (0 through 9). This is the most common source of off-by-one errors:

length = 14

// WRONG: loops 15 times (0 to 14 inclusive)
for i = 0 to length
    // processes bar_index 0..14 — one too many

// CORRECT: loops 14 times (0 to 13 inclusive)
for i = 0 to length - 1
    // processes bar_index 0..13

// Manual moving average example (correct)
total = 0.0
for i = 0 to length - 1
    total += close[i]
myMA = total / length
plot(myMA)

3. Lookback Calculations (Most Common Use Case)

//@version=5
indicator("Custom Lookback", overlay=false)

length = input.int(20, "Length", minval=1)

// Find highest high over last N bars (equivalent to ta.highest)
highestHigh = high
for i = 1 to length - 1
    if high[i] > highestHigh
        highestHigh := high[i]

// Find how many bars ago price was above a threshold
barsAbove = 0
threshold = ta.sma(close, 50)
for i = 0 to length - 1
    if close[i] > threshold
        barsAbove += 1

// Calculate a weighted average (more weight to recent bars)
weightedSum = 0.0
weightTotal = 0.0
for i = 0 to length - 1
    weight = length - i    // recent bars get higher weight
    weightedSum += close[i] * weight
    weightTotal += weight
wma = weightedSum / weightTotal
plot(wma, "WMA")

4. Iterating Arrays

//@version=5
indicator("Array Iteration")

// Build an array of the last 5 closing prices
prices = array.new_float(5)
for i = 0 to 4
    array.set(prices, i, close[i])

// Traditional index-based iteration
total = 0.0
for i = 0 to array.size(prices) - 1
    total += array.get(prices, i)
avgPrice = total / array.size(prices)

// Pine Script v5: for-in syntax (cleaner)
levels = array.from(support1, support2, resistance1, resistance2)
for level in levels
    hline(level, color=color.gray, linestyle=hline.style_dashed)

// for-in with index
for [idx, val] in levels
    label.new(bar_index, val, str.tostring(idx), style=label.style_label_left)

5. The "Loop Too Long" Error and How to Avoid It

Pine Script limits loop execution time. Loops that process too many bars or iterations produce: "Script could not be translated from: Loop is too long (~500ms)".

Three fixes:

// Fix 1: Use built-in functions instead of manual loops
// SLOW: manual loop for highest high
highestHigh = high
for i = 1 to 499
    if high[i] > highestHigh
        highestHigh := high[i]

// FAST: built-in — Pine computes this natively
highestHigh = ta.highest(high, 500)

// Fix 2: Limit the range dynamically
maxLookback = math.min(bar_index, 100)  // don't look back further than bars available
for i = 0 to maxLookback - 1
    // process

// Fix 3: Restructure — accumulate instead of looking back
// BAD: O(N²) — scans history on every bar
// GOOD: running sum — O(N) total
runningSum = 0.0
if bar_index >= length - 1
    for i = 0 to length - 1
        runningSum += close[i]  // same result but limit to when data is available

6. for vs while in Pine Script

  • Use for i = 0 to N when you know the exact number of iterations in advance — lookbacks, array processing.
  • Use while condition when the number of iterations depends on data — searching for a level, converging to a value.
  • Pine Script does NOT support break to exit a for loop early. Workaround: use a flag variable and if not done guards inside the loop.
// No break — use a found flag instead
found = false
foundIndex = -1
for i = 0 to 49
    if not found and close[i] < ta.sma(close, 20)[i]
        found := true
        foundIndex := i

For plot visualization after your loop calculations, see the Pine Script plot() guide. For strategies that use loop-based entries, see the strategy.entry guide.

Summary

Pine Script for loops run from start to end (inclusive) — always use to length - 1 when you want N iterations. Use by step to skip values or count down. Prefer built-in functions (ta.highest, ta.sma) over manual loops when available — they're significantly faster. For early exit, use a boolean flag instead of break since Pine Script's for loop doesn't support it.