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
Loops add computational overhead. When possible, use built-in functions like highest(), lowest(), sum() which are optimized.