request.security() in Pine Script: Multi-Timeframe Without Surprises

request.security() is a Pine Script function that fetches data from any symbol or timeframe, not just the one on your current chart. You can pull OHLCV values, custom calculations, or entire indicator outputs from another context and display them in your active script.
Ever found yourself on a 1-minute chart needing the daily trend? Or trading SPY but wanting to watch what the VIX is doing at the same time? That's what this function supports.
The requested context has its own bars and confirmation timing. An expression that compiles can still use an invalid timeframe or produce changing values on realtime bars.
The basic syntax
Here's the structure:
data = request.security(symbol, timeframe, expression, gaps, lookahead)
The parameters break down like this:
- symbol: The ticker you want ("NASDAQ:AAPL" or "BINANCE:BTCUSDT")
- timeframe: The timeframe ("1D", "240", "15", etc.). Hours use minutes:
"60"is one hour and"240"is four hours; Pine has noHunit. See timeframe formats - expression: What you want (close, high, low, or a custom calc)
- gaps: Handles missing data (optional)
- lookahead: Controls how requested values map to historical bars (optional; defaults to
barmerge.lookahead_off). It does not alone guarantee non-repainting values
Here's the simplest example — pull the daily close onto any intraday chart:
//@version=5
indicator("Daily Close on Intraday Chart")
daily_close = request.security(syminfo.tickerid, "1D", close)
plot(daily_close, "Daily Close", color.blue, linewidth=2)
This intentionally plots the developing daily close. On realtime intraday bars it can change before the daily bar closes, so historical results after reload can differ. Use confirmed values when that distinction matters.
Common applications
Multi-timeframe trend analysis: Display daily or weekly averages on an intraday chart. Distinguish the developing higher-timeframe value from the last confirmed value. The multi-timeframe analysis guide provides additional context.
Cross-symbol comparisons: Request a benchmark or sector ETF alongside a stock. Align sessions and available data before comparing changes; different markets need not update at the same time.
Indicator comparisons: Evaluate the same RSI or moving-average calculation in multiple contexts. The request evaluates the expression in the requested context, not by resampling an already-computed chart result.
Building a multi-timeframe RSI
This indicator compares current RSI with three requested timeframes. Its requested RSI values are developing values, not confirmed higher-timeframe signals:
//@version=5
indicator("Multi-Timeframe RSI", shorttitle="MTF RSI")
// Input parameters
rsi_length = input.int(14, "RSI Length", minval=1)
htf1 = input.timeframe("60", "Higher Timeframe 1")
htf2 = input.timeframe("240", "Higher Timeframe 2")
htf3 = input.timeframe("1D", "Higher Timeframe 3")
// Calculate RSI for current timeframe
current_rsi = ta.rsi(close, rsi_length)
// Request RSI from higher timeframes
htf1_rsi = request.security(syminfo.tickerid, htf1, ta.rsi(close, rsi_length))
htf2_rsi = request.security(syminfo.tickerid, htf2, ta.rsi(close, rsi_length))
htf3_rsi = request.security(syminfo.tickerid, htf3, ta.rsi(close, rsi_length))
// Plot everything
plot(current_rsi, "Current TF RSI", color.white)
plot(htf1_rsi, "Requested TF 1 RSI", color.yellow)
plot(htf2_rsi, "Requested TF 2 RSI", color.orange)
plot(htf3_rsi, "Requested TF 3 RSI", color.red)
// Add overbought/oversold levels
hline(70, "Overbought", color.red, linestyle=hline.style_dashed)
hline(30, "Oversold", color.green, linestyle=hline.style_dashed)
The defaults request hourly, four-hour, and daily RSI. Choose a chart timeframe below all three when studying higher-timeframe behavior. Different RSI readings do not, by themselves, identify a trend or a profitable trade. Changing the input timeframes changes what the plotted lines represent.
Limits and confirmation timing
Request limits: Current TradingView documentation allows 40 unique request.*() requests, or 64 on the Ultimate plan. Repeated identical requests generally reuse data. Tuples can fetch several values from one context, but do not remove all request, tuple-size, or memory limits.
Developing higher-timeframe values: lookahead_off avoids historical future leakage for an unoffset request, but the live higher-timeframe bar remains unconfirmed and can repaint after reload. For confirmed HTF data, TradingView documents requesting the previous bar's expression with lookahead_on. This deliberately adds one HTF bar of latency; using lookahead_on without that offset would leak future data into historical bars.
//@version=5
indicator("Confirmed Higher-Timeframe RSI")
htf = input.timeframe("1D", "Higher timeframe")
length = input.int(14, "RSI length", minval=1)
if timeframe.in_seconds(htf) <= timeframe.in_seconds()
runtime.error("Choose a timeframe higher than the chart timeframe.")
confirmedRsi = request.security(syminfo.tickerid, htf, ta.rsi(close, length)[1], lookahead=barmerge.lookahead_on)
plot(confirmedRsi, "Previous confirmed HTF RSI", color=color.blue)
The guard rejects equal or lower timeframes. Check this example on an intraday time-based chart with a daily input; the value updates when a new daily period begins, using the completed daily bar.
Lower timeframes: request.security() can request a lower timeframe, but returns a single intrabar value per chart bar. Use request.security_lower_tf() when an array of available intrabars is needed.
These behaviors and limits are documented in TradingView's other timeframes and data guide.
Expressions, inputs, and gaps
Custom expressions: You're not limited to OHLC. Request any formula:
// Request a custom calculation from daily timeframe
daily_volatility = request.security(syminfo.tickerid, "1D", ta.stdev(close, 20))
Variable-based timeframes: Store your inputs for cleaner code:
//@version=5
indicator("Requested Timeframe SMA")
htf = input.timeframe("240", "Requested Timeframe")
ma_length = input.int(20, "MA Length", minval=1)
htf_ma = request.security(syminfo.tickerid, htf, ta.sma(close, ma_length))
plot(htf_ma, "Requested SMA")
Gap handling: Choose how missing data behaves:
// Different gap handling options
continuous_data = request.security(symbol, timeframe, close, gaps=barmerge.gaps_off)
with_gaps = request.security(symbol, timeframe, close, gaps=barmerge.gaps_on)
These are fragments to place in a script with symbol and timeframe defined. Gaps concern alignment and availability of confirmed values; they are not proof of missing source data. gaps_off can return developing values in realtime.
Tuple expressions to consolidate requests: Pack multiple values from the same context into one request:
[htf_ma, htf_rsi] = request.security(syminfo.tickerid, "1D", [ta.sma(close, 20), ta.rsi(close, 14)])
One request returns two values from the same context; other platform limits still apply.
If you're getting started and want to experiment without chasing syntax errors, visual tools like Pineify's indicator builder handle request.security() behind the scenes. Review the generated timeframe inputs and confirmation behavior before relying on the output.
Frequently Asked Questions
What does request.security() do in Pine Script?
It lets your script pull OHLCV data or custom values from a different symbol or timeframe than the one displayed on your chart. Think of it as a data bridge — you stay on your chart, and the function fetches data from somewhere else.
What are the required parameters for request.security()?
Three are required: symbol (like "NASDAQ:AAPL"), timeframe ("1D"), and expression (close, or a formula). This guide focuses on the optional gaps and lookahead parameters; the function has additional optional parameters in the reference manual.
How do I avoid repainting when using request.security()?
For confirmed higher-timeframe values, request the prior bar's expression with lookahead=barmerge.lookahead_on and ensure the requested timeframe is strictly higher. This delays output until confirmation. lookahead_off alone does not stop developing HTF values changing on realtime bars.
Can I request data from a lower timeframe with request.security()?
Yes, but it returns only one intrabar value per chart bar, not every intrabar. Use request.security_lower_tf() to work with arrays of available intrabar values.
How many request.security() calls can I use in one script?
The documented limit is 40 unique request.*() requests, or 64 on Ultimate. Identical repeated requests can reuse data. Tuple expressions can consolidate values requested from the same context.
What is the difference between barmerge.gaps_on and barmerge.gaps_off?
gaps_on returns na where a newly confirmed requested value is unavailable. gaps_off fills historical gaps with confirmed values and can provide developing values in realtime. A gap does not necessarily mean source data is missing.
Can I pass a custom calculation as the expression argument?
Yes. It supports calculations such as ta.rsi(close, 14), ta.sma(close, 20), and ta.stdev(close, 20); supported types and expressions are subject to the function's rules. Pine Script evaluates it in the context of the requested symbol and timeframe, not the chart's current context.


