Pine Script Data Fetching & Architecture

Pine Script request.security: Complete Multi-Timeframe and Symbol Guide

In Pine Script, request.security() requests data from another ticker, market, or timeframe without altering the current chart resolution. It accepts symbol, timeframe, expression, gaps, and lookahead arguments. To prevent severe lookahead bias and repainting on historical bars, developers must combine barmerge.lookahead_off with historical offset indexing (such as close[1]) when requesting completed higher-timeframe data.

Build MTF Scripts with AI Agent

request.security() syntax and parameters in Pine Script v6

The request.security() function is Pine Scripts primary mechanism for intermarket analysis and multi-timeframe (MTF) trading logic. Whether pulling SPY index returns onto an individual stock chart, comparing gold against the US dollar, or displaying a 4-hour EMA on a 5-minute execution chart, request.security handles the data alignment between differing resolution feeds.

ParameterTypeDefaultFunction / Behavior
symbolsimple stringRequiredTicker ID (e.g. syminfo.tickerid or "INDEX:SPX")
timeframesimple stringRequiredTimeframe string: "1", "5", "60", "240", "D", "W", "M"
expressionany type/tupleRequiredThe calculation or series to evaluate (e.g. close, ta.ema(close, 50), [high, low])
gapsbarmerge.gaps_*barmerge.gaps_offbarmerge.gaps_off carries previous value forward; gaps_on returns na when no bar exists
lookaheadbarmerge.lookahead_*barmerge.lookahead_offControls whether historical calculations access future completed bars prematurely
ignore_invalid_symbolsimple boolfalseIf true, returns na instead of halting execution when a symbol is invalid

How to prevent lookahead bias and repainting in request.security

The most dangerous pitfall in Pine Script is historical lookahead bias caused by improper request.security configuration. When you request a higher timeframe (such as daily) from an intraday chart (such as 15-minute), TradingViews backtesting engine can accidentally look ahead to the daily close before the 15-minute bar actually occurred. This produces impossibly profitable backtests that fail in live trading.

MethodSyntaxHistorical BehaviorRepaints?
Lookahead ON (Danger)request.security(sym, "D", close, lookahead = barmerge.lookahead_on)Uses 4:00 PM daily close at 9:30 AM in the morningYES - severe repainting and false backtests
Unshifted Lookahead OFFrequest.security(sym, "D", close, lookahead = barmerge.lookahead_off)Daily close updates intra-day, but creates real-time vs history mismatchYES - intra-day repainting on current day
Safe Shifted Index [1]request.security(sym, "D", close[1], lookahead = barmerge.lookahead_off)Uses the closed previous day close throughout the current dayNO - 100% stable, non-repainting in live and backtest

Complete multi-timeframe indicator code example in Pine Script v6

This script demonstrates how to request a higher-timeframe 200 EMA and Daily High/Low using tuple batching and non-repainting offsets.

Pine Script v6: Non-repainting multi-timeframe EMA and Daily rangepinescript
//@version=6
indicator("MTF Trend & Range [v6]", overlay = true)

// User settings
htfTimeframe = input.timeframe("D", "Higher Timeframe")
emaLength = input.int(200, "HTF EMA Length")

// Calculate the EMA expression on the higher timeframe
// Using [1] offset ensures we only look at COMPLETED higher-timeframe bars
htfEmaCalc = ta.ema(close, emaLength)[1]

// Batch request multiple values as a tuple to optimize performance
[htfEma, prevHigh, prevLow] = request.security(
     syminfo.tickerid, 
     htfTimeframe, 
     [htfEmaCalc, high[1], low[1]], 
     barmerge.gaps_off, 
     barmerge.lookahead_off
)

// Plots
plot(htfEma, "Daily 200 EMA (Non-Repainting)", color = color.yellow, linewidth = 2)
plot(prevHigh, "Previous Day High", color = color.green, style = plot.style_circles)
plot(prevLow, "Previous Day Low", color = color.red, style = plot.style_circles)

// Background color based on HTF trend
isBullishTrend = close > htfEma
bgcolor(isBullishTrend ? color.new(color.green, 95) : color.new(color.red, 95), title = "Trend Background")

Tuple batching and resource limits optimization

TradingView limits each script to a maximum number of concurrent request.security() calls (usually 40). If you make individual calls for open, high, low, close, volume, and multiple EMAs, you quickly exhaust your quota and degrade chart performance. Always batch requests into tuples: request.security(..., [open[1], high[1], low[1], close[1]]) counts as only ONE security call while retrieving all four price series at once.

  • Batch expressions into tuples: Group open, high, low, close, and indicators into a single tuple return [val1, val2, val3].
  • Avoid calling security inside user functions: Placing request.security inside a loop or custom function called multiple times creates duplicate request contexts.
  • Use timeframe.period comparisons: Ensure the requested timeframe is strictly greater than or equal to the chart timeframe to avoid lower-timeframe resolution misalignment.
Where Pineify fits

Pine Script AI Coding Agent

Generate multi-timeframe indicators, batch tuple requests, and eliminate lookahead repainting bugs automatically with Pineify AI Coding Agent.

Also useful: Pine Script Error Lab. Resolve "too many request.security calls" and unexpected historical offset buffer errors in Pine Script v6.

Build MTF Scripts with AI Agent

Frequently asked questions

Multi-timeframe data analysis requires careful alignment of market sessions and bar timestamps. Unaligned trading sessions across international exchanges may introduce data gaps.

Sources and verification