Repository navigation
Description
Trigger
A script chooses the timeframe of request.security with a condition that reads a chart series value (close, open, a history read, a ta.* result, bar_index, ...). TradingView evaluates the condition on every bar and requests the timeframe that bar selects.
Silent wrong value (compiles, runs, different result)
The generated code computes the timeframe once, before the first bar, and keeps that one choice for the whole run. The script runs without any diagnostic, and every value that depends on the requested data (entries, quantities, exits) can differ from TradingView from the first bar where the choice would differ. Four shapes are affected:
- An arm that is a timeframe input:
tf_slow = input.timeframe("240", "slow timeframe")
pick_tf = close > open ? tf_slow : "60"
v = request.security(syminfo.tickerid, pick_tf, bar_index)
- An arm that is the chart's own timeframe:
pick_tf = close > open ? timeframe.period : "240"
v = request.security(syminfo.tickerid, pick_tf, bar_index)
- A requested tuple:
pick_tf = close > open ? "240" : "1D"
[c, n] = request.security(syminfo.tickerid, pick_tf, [close, bar_index])
- A timeframe passed through the parameter of a helper function:
sec_val(tf) => request.security(syminfo.tickerid, tf, bar_index)
v = sec_val(close > open ? "240" : "1D")
The same applies to the plain literal form close > open ? "60" : "240".
In our checks of v1.9.1 against TradingView over the same two months, 67 to 75 of 205 entries differed in each of these shapes.
Compile failure (loud)
Written as an if or switch expression, the choice does not compile in v1.9.1: the C++ build stops with error: expected primary-expression. This is true for every scalar if that chooses a request timeframe, whatever its condition, including conditions that never change during the run (an input, timeframe.isintraday, chart.is_standard, a function returning a constant). Scripts written with a ternary on an input or on timeframe.* (not a chart series value) are not affected.
Affected versions
v1.9.1 (checked). Earlier releases have not been checked.
Workaround
Request each timeframe with a literal (or the same input) and choose the value per bar. The generated code then registers one request per timeframe and the condition only selects between their results. For the four shapes above:
// 1. input arm
tf_slow = input.timeframe("240", "slow timeframe")
a = request.security(syminfo.tickerid, tf_slow, bar_index)
b = request.security(syminfo.tickerid, "60", bar_index)
v = close > open ? a : b
// 2. chart-timeframe arm
a = request.security(syminfo.tickerid, "60", bar_index) // the chart timeframe, written out
b = request.security(syminfo.tickerid, "240", bar_index)
v = close > open ? a : b
// 3. tuple
[sc, sn] = request.security(syminfo.tickerid, "240", [close, bar_index])
[dc, dn] = request.security(syminfo.tickerid, "1D", [close, bar_index])
c = close > open ? sc : dc
n = close > open ? sn : dn
// 4. helper
a = request.security(syminfo.tickerid, "240", bar_index)
b = request.security(syminfo.tickerid, "1D", bar_index)
v = close > open ? a : b
For form 2, write the chart's timeframe as a literal that matches the chart you run on. The same two-request shape replaces any if or switch choice. These forms produce the same trades as the fixed build described below, whose results equal TradingView's entry by entry in our checks. One limit: a requested expression with a long history window (for example a 50-bar average) differs from TradingView only inside TradingView's own warm-up stretch of the first bars.
Status
The next patch release follows the condition on every bar for these shapes and for the if/switch forms. Two cases stay a located compile error with an explanatory message: a timeframe whose set of possible values is not fixed at compile time (a computed string), and a requested expression that keeps state across bars (var/varip). A timeframe passed through a helper function's parameter becomes a located compile error in the next patch release instead of a silent value; use the workaround above.
Activity
luisleo526 commentedon Nov 2, 2026
Additional measurements on v1.9.1: for the plain form
close > open ? "60" : "240", 245 of 477 entries (51%) differed from TradingView over the same two months; for the helper-parameter shape, one further entry was missing in addition to the 67 that differed.luisleo526 commentedon Nov 2, 2026
Follow-up: the trigger includes a
varcounter or any state updated from bar to bar, and a request inside a loopThe trigger in the description lists chart series values. It includes any state that is updated from one bar to the next and then chooses the timeframe, for example a counter declared with
varand incremented on every bar. Measured on v1.9.1, BTCUSDT 1h over two months (2024-01-01 to 2024-03-01), against TradingView's own entries. The result depends on how the choice is spelled:Written as an
ifexpression (pick_tf = if step_count > 3 ...): v1.9.1 does not build. The C++ compile stops; no wrong value is produced.Written as a ternary (
pick_tf = step_count > 3 ? "240" : "1D"): v1.9.1 builds and runs and uses ONE fixed timeframe for the whole run. Joined by entry time to TradingView's list on v1.9.1: the run has 204 entries and TradingView has 205; 68 are equal, 136 are different, and 1 is only in TradingView's list. TradingView switches the timeframe when the counter passes 3.A
request.securitycall inside aforloop whose counter chooses the timeframe: v1.9.1 does not build (the generated code refers to the timeframe variable outside its scope). TradingView accepts the script.Workaround for each form, built and run on v1.9.1 and equal to TradingView on all 205 entries: request each timeframe once and select the result.
Only the
ifexpression was checked for the failing-to-build spelling; aswitchwas not. Earlier versions were not checked.We will post here when a release changes these results.
luisleo526 commentedon Nov 2, 2026
Follow-up 2: more spellings of a timeframe chosen per bar, a helper that chooses its own timeframe, and a change of plan
All measurements below are on v1.9.1, BTCUSDT 1h over two months (2024-01-01 to 2024-03-01), against TradingView's own entries joined by entry time. Each script below was also run on TradingView.
More spellings that keep one fixed timeframe (silent wrong value)
Each of these builds and runs on v1.9.1 without a diagnostic and uses one fixed timeframe for the whole run, while TradingView chooses the timeframe on every bar. For the first three the run has 204 entries and TradingView has 205; for the fourth both have 205.
137 entries equal, 67 different, 1 only in TradingView's list.
137 equal, 67 different, 1 only in TradingView's list.
varcounter:137 equal, 67 different, 1 only in TradingView's list.
request.security_lower_tfwith a timeframe chosen by the chart bar:205 entries in both lists: 109 equal, 96 different.
The counts are per script and are not comparable across scripts: each script's quantity pattern differs.
A helper that chooses its own timeframe (loud)
v1.9.1 refuses to build this script: "request.security timeframe cannot be resolved before the first bar on the call path fetch_v(): it reads 'close', a series". TradingView accepts it.
Workarounds, each built and run on v1.9.1
For each script above, the form below builds on v1.9.1 and its entries are equal to TradingView's on all 205 entries. TradingView computes each workaround exactly as it computes the original script: the two trade lists are identical.
Change of plan
The Status section of the description said that two cases stay a located compile error (a computed timeframe string, and a requested expression that keeps state across bars with
var/varip), and that a timeframe passed through the parameter of a helper function becomes a located compile error in the next patch release. That plan has changed. These forms will be computed on every bar as TradingView does, including stopping with a runtime error where TradingView stops (for example a computed string that is not a valid timeframe), instead of being refused when the script is built. There is no release date yet; a release will carry all of these together, and we will post here when a release changes these results. Until then the shapes in the description and in the two follow-ups behave as described, and the workarounds apply.Let a loop counter be read in its own end and step; refuse names read…
Stop an endless counted loop as TradingView does, count float steps b…
luisleo526 commentedon Nov 9, 2026
Fixed: the reported form was fixed in v1.10.0, and the remaining case (a helper argument that chooses the timeframe) is in v1.11.0, with a test that checks the helper's choice is followed on every bar (#355). Closing.