Skip to main content
Control flow structures for iteration and conditional logic in your indicators.

for Loop

Execute code a fixed number of times.

Syntax

for (var i = 0; i < count; i++) {
  // loop body
}

Example

//@version=2

define(title="Custom Average", position="offchart", axis=true);

timeseries ohlcvData = ohlcv(symbol=currentSymbol, exchange=currentExchange);

// Calculate custom weighted average
var sum = 0.0;
var weightSum = 0.0;

for (var i = 0; i < 10; i++) {
  var weight = 10 - i;  // Higher weight for recent bars
  sum += ohlcvData.close[i] * weight;
  weightSum += weight;
}

var weightedAvg = sum / weightSum;

plotLine(value=weightedAvg, width=2, colors=["blue"], label=["Weighted Avg"], desc=["Custom Weighted Average"]);

while Loop

Execute code while a condition is true.

Syntax

while (condition) {
  // loop body
}

Example

//@version=2

define(title="Count Consecutive", position="offchart", axis=true);

timeseries ohlcvData = ohlcv(symbol=currentSymbol, exchange=currentExchange);

// Count consecutive green candles
var count = 0;
var i = 0;

while (i < 10 && ohlcvData.close[i] > ohlcvData.open[i]) {
  count++;
  i++;
}

plotLine(value=count, width=2, colors=["green"], label=["Green Count"], desc=["Consecutive Green Candles"]);
Always ensure while loops have an exit condition to prevent infinite loops. The 500ms execution limit will terminate runaway scripts.

if/else Statements

Conditional execution of code.

Syntax

if (condition) {
  // code if true
} else if (anotherCondition) {
  // code if another condition
} else {
  // code if all conditions false
}

Example

//@version=2

define(title="RSI Zones", position="offchart", axis=true);

timeseries ohlcvData = ohlcv(symbol=currentSymbol, exchange=currentExchange);
var rsiValue = rsi(source=ohlcvData.close, period=14);

var zone = "";
var colorIndex = 0;

if (rsiValue > 70) {
  zone = "Overbought";
  colorIndex = 0;  // Red
} else if (rsiValue < 30) {
  zone = "Oversold";
  colorIndex = 1;  // Green
} else {
  zone = "Neutral";
  colorIndex = 2;  // Blue
}

plotLine(value=rsiValue, width=2, colors=["red", "green", "blue"], colorIndex=colorIndex, label=["RSI"], desc=[zone]);

Ternary Operator

Shorthand for simple if/else expressions.

Syntax

var result = condition ? valueIfTrue : valueIfFalse;

Example

timeseries ohlcvData = ohlcv(symbol=currentSymbol, exchange=currentExchange);

// Conditional color
var isGreen = ohlcvData.close > ohlcvData.open;
var colorIndex = isGreen ? 0 : 1;

// Conditional value
var displayValue = isGreen ? ohlcvData.high : ohlcvData.low;

break Statement

Exit a loop early.

Example

// Find first bar where RSI crossed above 70
var crossBar = -1;

for (var i = 0; i < 100; i++) {
  if (rsiValue[i] > 70 && rsiValue[i+1] <= 70) {
    crossBar = i;
    break;  // Exit loop once found
  }
}

continue Statement

Skip to the next iteration.

Example

// Sum only positive changes
var positiveSum = 0.0;

for (var i = 0; i < 20; i++) {
  var change = ohlcvData.close[i] - ohlcvData.close[i+1];

  if (change <= 0) {
    continue;  // Skip negative changes
  }

  positiveSum += change;
}

Practical Examples

Custom High-Low Range

//@version=2

define(title="Custom Range", position="offchart", axis=true);

var period = input(name="period", type="number", defaultValue=20, label="Period");

timeseries ohlcvData = ohlcv(symbol=currentSymbol, exchange=currentExchange);

// Find highest and lowest manually
var highest = ohlcvData.high[0];
var lowest = ohlcvData.low[0];

for (var i = 1; i < period; i++) {
  if (ohlcvData.high[i] > highest) {
    highest = ohlcvData.high[i];
  }
  if (ohlcvData.low[i] < lowest) {
    lowest = ohlcvData.low[i];
  }
}

var range = highest - lowest;

plotLine(value=range, width=2, colors=["purple"], label=["Range"], desc=["Price Range"]);

Pattern Detection

//@version=2

define(title="Three White Soldiers", position="onchart", axis=false);

timeseries ohlcvData = ohlcv(symbol=currentSymbol, exchange=currentExchange);

// Check for three consecutive green candles with higher closes
var isPattern = true;

for (var i = 0; i < 3; i++) {
  var isGreen = ohlcvData.close[i] > ohlcvData.open[i];
  var higherClose = i == 0 || ohlcvData.close[i] < ohlcvData.close[i-1];

  if (!isGreen || !higherClose) {
    isPattern = false;
    break;
  }
}

var signalValue = isPattern ? ohlcvData.low[0] : na;

plotShape(value=signalValue, shape="triangle", width=2, colors=["green"], label=["Pattern"], desc=["Three White Soldiers"]);

Moving Average Ribbon

//@version=2

define(title="MA Ribbon", position="onchart", axis=false);

timeseries ohlcvData = ohlcv(symbol=currentSymbol, exchange=currentExchange);

var periods = [10, 20, 30, 40, 50];
var colors = ["green", "lime", "yellow", "orange", "red"];

// Calculate and plot multiple MAs
for (var i = 0; i < 5; i++) {
  var maValue = ema(source=ohlcvData.close, period=periods[i]);
  plotLine(value=maValue, width=1, colors=[colors[i]], label=[concat("EMA ", periods[i])], desc=[concat("EMA ", periods[i])]);
}

Tips

Execution Limits

Scripts must complete within 500ms. Avoid very long loops or nested loops that could exceed this limit.

Loop Best Practices

  • Always use finite loop bounds
  • Prefer for loops when iteration count is known
  • Use break to exit early when possible
  • Avoid modifying loop variables inside the loop body

Performance

Loops add computational overhead. When possible, use built-in functions like highest(), lowest(), sum() which are optimized.