Build1 distinct publisher3 min readPublished
TradingView documents that request.security() defaults to lookahead_off for a reason. Scripts that override it produce entry signals no live bot could have acted on. Those signals become visible only after the chart reloads and the bars recalculate.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
Follow any of these and your For You feed starts watching them — no settings page required.
invest
Bitcoin's close under the 200-week line is a sizing input, not a forecast2 distinct publishers
Run the arithmetic on the configuration in the example. The chart is 15 minutes and the call requests `"60"` with `lookahead=barmerge.lookahead_on` [6]. Sixty divided by fifteen is four, so four chart bars sit inside each hourly bar, and three of them close before the hour does. On historical data, each of those three compares its own close against an hourly close that had not happened yet at that timestamp [7]. That is three of every four bars, 75%, reading a number a live bot did not have [13]. The fourth bar is honest, because it closes when the hour closes.
The ratio depends on the pairing of chart resolution and requested timeframe. Move the same call to a 5-minute chart and it is 11 of 12, about 92% [13]. Put it on a 1-hour chart against `"60"` and there is nothing left to leak. So the size of the distortion in your own tester report is a function of your chart resolution against the requested timeframe, and it is worth computing before you argue about fees.
Detection is the hard part, and it is hard for a documented reason. TradingView's docs state that on the currently-forming realtime bar, a lookahead series and a no-lookahead series plot the same value, because the bar has not closed and there is no future to borrow from yet; the divergence appears retroactively when that bar becomes historical and gets recalculated against the full record, which the docs call repainting [8]. Watching signals fire in a paper session therefore confirms nothing about the backtest, since the numbers only part company after a reload [9]. The tester fills the value in without complaint [7]. It is answering the question you asked.
There is a second mechanism with the same shape. When the requested timeframe is at or below the chart's own resolution, the docs say the expression is evaluated in the lower-timeframe context but returns results from only a single intrabar per chart bar [10], and the same `lookahead` argument picks which one: the first intrabar with `lookahead_on`, the last with `lookahead_off` [11]. The return semantics are simply narrower than the mental model of "I asked for 1-minute data" implies, and nothing in the script is actually broken.
The remediation is cheap, which is the argument for doing it before you touch anything else. Grep every `request.security()` call for a `lookahead` argument; a call that omits it is on the safe default of `barmerge.lookahead_off` [3]. For each call that sets `lookahead_on`, check for an explicit historical offset such as a trailing `[1]`, and treat its absence as a probable leak [12]. The platform's own warning is scoped exactly there: `lookahead_on` without an offset [5].
For a tester report to transfer to live execution, one thing has to be true of every higher-timeframe call in the script. The value it returns must already have been closed at the timestamp of the bar reacting to it. `lookahead_on` with no offset is a statement that you have decided not to require that.
Ranked by verification strength, evidence, and original report placement.
The worked example is a //@version=6 strategy that sets htfClose = request.security(syminfo.tickerid, "60", close, lookahead=barmerge.lookahead_on) and enters long when close > htfClose.
On historical bars that example compares current price against the closed 1-hour value, including, for intraday bars still inside that hour, a close that in a live sense had not happened yet; the backtest engine has the full historical record and fills that value in without complaint.
The suggested check is to grep every request.security() call for a lookahead argument, treat unset calls as on the safe default, give any lookahead_on call a second look, and verify whether the requested series has an explicit historical offset such as a trailing [1]; without one, data is very likely leaking into the backtest.
request.security() pulls a value computed on a different timeframe or symbol into the script's current context, for example checking the 1-hour trend from a 15-minute chart.
request.security() takes a lookahead parameter controlling how it fills values on historical bars; as of the current Pine Script version its documented default is barmerge.lookahead_off, which does not leak information from the future into the past.
TradingView's documentation warns: "When using barmerge.lookahead_on without an offset, ensure that it does not compromise the integrity of the script's logic by leaking future data into historical chart bars."
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 29, 2026
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Vendor docs, no citation trail
The mechanic itself is about as checkable as a single-author post gets: two direct quotes from TradingView's documentation and an eight-line strategy a reader can paste into a chart in a minute. What weakens it is provenance — neither quote carries a version, date or link, and Pine's defaults have moved between versions, so verifying the 'default is lookahead_off' claim means going to find the page yourself. The prevalence framing around the mechanic gets no support at all.
Nobody counted
There is no measurement of how far this reaches. Nobody scanned TradingView's public script library for lookahead_on, nobody sampled strategies, and the author explicitly says this case did not come out of client work — so even his own audit numbers stay off the page. The claim that a higher-timeframe filter is 'one of the most common things people add' is plausible and entirely unquantified.
Mechanism sound, reach asserted
The headline promises your backtest gets tomorrow's hourly close, and the documented behaviour actually delivers that — the drama is earned. The post also argues against its own interest in useful places: the default is safe, lookahead_on is a legitimate parameter, the failure is subtle rather than scandalous. The overstatement sits in the reach words: 'usually blamed on slippage', 'plenty of forum answers', 'very likely leaking'. Each does quiet work in making a real but narrow parameter trap feel like a widespread condition.
Audit pitch, disclosed upfront
The last two lines name the author's business — a technical audit service called Honest Backtest — and state that the piece first appeared on that company's blog. This is content marketing with the receipt attached: the failure it teaches you to fear is the failure the service is sold to find. Two things temper it. The disclosure is voluntary and unambiguous, and the technical payload does not require trusting the seller, because TradingView's docs either say what he quotes or they do not.
One voice, checkable subject
Single publisher, single author, no replication — ordinarily that caps confidence hard. It caps it less here because the subject is documented platform behaviour rather than a private finding: a reader with a chart and the docs page can confirm or demolish the central claim without anyone's cooperation. What stays genuinely uncertain is scale, cost, and whether the quoted default still holds in the Pine version you happen to be running.