request.security() lookahead breaking change in Pine Script v6, which is why I'm publishing this standardized guide instead of answering one-off.
> Disclosure: This article contains affiliate links. We may earn a commission at no extra cost to you if you sign up through our links.
# Fix Pine Script v6 request.security() Lookahead Error (2026)
Upgrading custom indicators to Pine Script v6 triggers a hard compiler error on request.security(). The red line points to lookahead, claiming it is no longer a valid argument, or worse, your multi-timeframe (MTF) tool suddenly paints signals that vanish seconds later.
This is not a bug in your logic. TradingView deliberately restructured the request.security() signature in v6 to enforce strict data integrity. The platform removed the ability to toggle lookahead freely, forcing developers to explicitly define how gaps and bar merges are handled. If you ignore this, your backtests will lie to you, and live execution will fail.
This guide provides the exact syntax replacements, parameter breakdown, and verification steps to migrate your scripts to v6 compliance without losing functionality.
Why TradingView Broke request.security() in v6
In Pine Script v5 and earlier, the lookahead parameter controlled whether the function could access the current bar's data before it closed.
// Pine Script v5 Syntax (Broken in v6)
sma_1h = request.security(syminfo.tickerid, "60", ta.sma(close, 20), lookahead=barmerge.lookahead_on)
When lookahead=barmerge.lookahead_on was active, the function pulled the *current* higher-timeframe bar's data while it was still forming. This created a repainting loop. Your indicator would flash a buy signal based on a provisional close, but as the bar traded, that close value shifted. The signal would disappear. Backtests frequently showed artificially inflated win rates due to repainting; live accounts bled capital.
Pine Script v6 eliminates this ambiguity. The new architecture requires explicit gaps and lookahead declarations, with stricter defaults that prioritize confirmed historical data over speculative real-time values. The official documentation now mandates lookahead=barmerge.lookahead_off for production scripts to prevent future-function leaks (TradingView Pine Script Docs).
The v6 Syntax Fix: Step-by-Step
The migration requires updating parameter names and adopting the new barmerge enumeration constants. The v6 function signature is stricter about keyword arguments.
1. Replace lookahead_on with lookahead_off
If your v5 code relied on lookahead_on, you must switch to lookahead_off. TradingView v6 heavily restricts lookahead_on because it guarantees repainting on the current bar.
mtf_sma = request.security(syminfo.tickerid, timeframe.period, ta.sma(close, 20), lookahead=barmerge.lookahead_on)
New (v6 - Compliant):
mtf_sma = request.security(syminfo.tickerid, timeframe.period, ta.sma(close, 20), lookahead=barmerge.lookahead_off)
2. Explicitly Define the gaps Parameter
V5 handled gaps implicitly. V6 requires you to state how the function treats missing time periods (weekends, exchange halts, or low-liquidity crypto pairs). The default is barmerge.gaps_off, which skips missing periods and calculates only on available bars.
mtf_rsi = request.security(
syminfo.tickerid,
"240",
ta.rsi(close, 14),
gaps=barmerge.gaps_off,
lookahead=barmerge.lookahead_off
)
3. Resolve "Lookahead is not a valid argument" Compiler Errors
If you paste older v4/v5 scripts into a v6 environment, the compiler throws: Cannot call 'request.security' with arguments.... This occurs because v6 enforces keyword arguments. Positional ordering is stricter, and mixing positional with keyword arguments breaks the parser.
//@version=6
indicator("MTF SMA Fix", overlay=true)
res = input.timeframe("60", "Resolution")
sma_val = request.security(
syminfo.tickerid,
res,
ta.sma(close, 50),
gaps=barmerge.gaps_off,
lookahead=barmerge.lookahead_off
)
plot(sma_val, color=color.blue, linewidth=2)
Parameter Breakdown: gaps, lookahead, and type
Like what you're reading? Try it yourself โ this link supports ChartedTrader at no cost to you.
Try TradingView Free โUnderstanding the three core parameters prevents silent logic errors.
| Parameter | v5 Behavior | v6 Requirement | Impact on Trading |
|---|---|---|---|
gaps | Implicit | barmerge.gaps_off (default) or barmerge.gaps_on | gaps_off skips weekends/halts. gaps_on treats gaps as zero-volume bars, which can distort moving averages. |
lookahead | barmerge.lookahead_on allowed | barmerge.lookahead_off enforced for safety | lookahead_off ensures signals only trigger on confirmed closes. Eliminates repainting. |
type | Rarely used | barmerge.mtime_one (default) | Controls how bars merge. mtime_one uses the first tick of the bar. btime aligns with exchange session closes. |
gaps=barmerge.gaps_off and lookahead=barmerge.lookahead_off is the correct configuration. Only use gaps_on if you are modeling continuous futures contracts where weekend gaps must be preserved as zero-volume periods.
Advanced Usage: Handling Multiple Timeframes Efficiently
Calling request.security() multiple times for the same timeframe can slow down chart rendering, especially on lower-tier plans. As of May 2026, TradingView's engine optimizes repeated calls, but it is still best practice to fetch raw data once and compute indicators locally.
sma_1h = request.security(syminfo.tickerid, "60", ta.sma(close, 20), lookahead=barmerge.lookahead_off)
ema_1h = request.security(syminfo.tickerid, "60", ta.ema(close, 20), lookahead=barmerge.lookahead_off)
Efficient (Single Call + Local Calculation):
close_1h = request.security(syminfo.tickerid, "60", close, lookahead=barmerge.lookahead_off)
sma_1h = ta.sma(close_1h, 20)
ema_1h = ta.ema(close_1h, 20)
This approach reduces server load, prevents redundant data fetching, and keeps your script compliant with TradingView's resource limits. It also ensures that both indicators use the exact same historical close values, eliminating micro-discrepancies that can occur when fetching data separately.
Verification Workflow: The Bar Replay Test
Fixing the syntax is only half the work. You must verify that your indicator no longer repaints. Follow this exact workflow:
1. Add your fixed indicator to a chart.
2. Click the Replay button on the toolbar. Step back 20 bars. 3. Press Play to advance bar by bar. 4. Watch the MTF signal. If a crossover or histogram flip changes *after* the higher-timeframe bar closes, you still have a lookahead leak.In v6 with lookahead_off, signals should appear exactly when the higher timeframe bar closes and remain static. If signals flicker during bar formation, you are likely still referencing close of the current bar inside the expression argument. Replace any close references with security(..., lookahead=barmerge.lookahead_off) to enforce historical-only data.
Common Migration Pitfalls
1. The ta.supertrend Lookahead Trap
Many traders wrap ta.supertrend in request.security to use it as a trend filter. Supertrend is highly sensitive to close prices. In v5, lookahead_on gave "early" signals. In v6, this is blocked.
The v6 Workaround:
Use the MTF Supertrend strictly as a directional filter, not an entry trigger. Reference the previous confirmed bar [1] to guarantee stability.
htf_supertrend = request.security(syminfo.tickerid, "240", ta.supertrend(20, 2), lookahead=barmerge.lookahead_off)
trend_bullish = close > htf_supertrend[1]
2. Mixing Timeframes in One Expression
V5 allowed complex expressions inside a singlerequest.security call. V6 parses these poorly and often throws type-mismatch errors. Break calculations into separate calls.
Bad (v6):
data = request.security(syminfo.tickerid, "60", ta.sma(close, 20) + ta.rsi(close, 14), lookahead=barmerge.lookahead_off)
Good (v6):
sma_1h = request.security(syminfo.tickerid, "60", ta.sma(close, 20), lookahead=barmerge.lookahead_off)
rsi_1h = request.security(syminfo.tickerid, "60", ta.rsi(close, 14), lookahead=barmerge.lookahead_off)
combined = sma_1h + rsi_1h
3. Ignoring the type Parameter for Futures
If you trade equity or commodity futures with roll dates, the default barmerge.mtime_one may misalign your MTF data with exchange session closes. Switch to type=barmerge.btime to force bar merging based on actual bar time rather than tick arrival.
Performance & Optimization Considerations
As of May 2026, TradingView's Pine Script v6 engine introduces stricter execution limits. Scripts that make excessive request.security() calls may hit the "Too many calls to request.security()" warning. To optimize:
- Cache results: Use
varorvaripto store fetched data when possible. - Limit resolutions: Avoid fetching data from extremely high timeframes (e.g., monthly) on low-timeframe charts. The engine must calculate every intermediate bar, which consumes significant resources.
- Use
request.securitysparingly: Only fetch data you actively plot or use for logic. Unused variables still consume computation cycles.
Risk Warning
> Risk Warning: Pine Script indicators are analytical tools, not financial advice. Multi-timeframe strategies carry inherent latency risks. Even with lookahead_off, data feeds from different brokers may have slight timestamp mismatches, causing execution slippage. Always backtest on out-of-sample data and forward-test on a paper account before deploying capital. Trading leveraged instruments amplifies both gains and losses.
FAQ
Q: Can I still uselookahead=barmerge.lookahead_on in v6?
A: Technically yes, but the compiler will flag it, and TradingView actively discourages it. It guarantees repainting on the current bar, which invalidates backtest accuracy. Stick to lookahead_off for live trading.
Q: Why does my indicator show na values after the fix?
A: na values appear when the higher timeframe bar hasn't closed yet and lookahead_off is active. This is correct behavior. The indicator waits for confirmation. If you need continuous plotting, use barstate.isconfirmed to conditionally plot only when the bar is closed.
Q: Does gaps=barmerge.gaps_off work for 24/7 crypto markets?
A: Yes. Crypto exchanges rarely have true data gaps. gaps_off simply tells the engine to ignore missing ticks and calculate based on available bars, which is ideal for continuous crypto pairs.
Q: How do I fix "Cannot call request.security with arguments" errors?
A: Ensure you are using keyword arguments (gaps=..., lookahead=...) rather than positional ones. V6 enforces strict keyword matching. Copy the exact signature from the official docs if the error persists.
Q: Will this fix work for request.security_lower_tf()?
A: Yes. The request.security_lower_tf() function follows the same v6 parameter rules. Replace lookahead_on with lookahead_off and explicitly define gaps to resolve compiler errors.
Final Checklist for v6 Compliance
Before publishing or deploying your updated indicator, verify these points:
- [ ] All
request.security()calls uselookahead=barmerge.lookahead_off. - [ ] The
gapsparameter is explicitly defined (usuallybarmerge.gaps_off). - [ ] Keyword arguments replace positional arguments.
- [ ] Bar Replay test shows zero signal movement after bar close.
- [ ] Script compiles without warnings in the Pine Editor.
- [ ] Performance warnings are resolved by caching or reducing calls.
request.security() lookahead error takes less than five minutes per script, but the payoff is a robust, non-repainting toolset that performs reliably in live markets. If you're optimizing strategy parameters alongside these fixes, review our guide on Pine Script Strategy Optimization. For users on the free plan hitting indicator limits, see how to combine multiple indicators into one script.
Upgrade your scripts today and trade with confirmed data.
> Try TradingView https://www.tradingview.com/?aff_id=163652 to test your v6 scripts in a live environment with real-time data.