Appearance
Pine compatibility
Will a script you wrote for TradingView run here, and give the same numbers? A Pine Script v6 text runs unchanged, and where TradingView's output has been captured the engine is held to it value for value. The tables below list every place we know of where it still reads differently, which ones are on purpose, and what TradingView refuses that runs here.
pine
//@version=6
indicator("Runs the same on both", overlay = true)
int len = input.int(20, "Length", minval = 1)
float basis = ta.sma(close, len)
float dev = 2 * ta.stdev(close, len)
plot(basis, "Basis", color.gray)
// fills, colours and bands read the same values on both platforms
p1 = plot(basis + dev, "Upper", color.teal)
p2 = plot(basis - dev, "Lower", color.teal)
fill(p1, p2, color.new(color.teal, 90))Which version runs
Every script runs on Pine Script v6's rules. No //@version line is read: a Pine text keeps //@version=6 because TradingView compiles by it, and an older version's script runs as if it were v6, so a v5 script that relies on v5 behaviour reads v6's. Earlier versions won't be supported.
A text that uses nothing this terminal adds is Pine Script, and runs as TradingView runs it. A text that uses any addition is AmenoScript, which runs leak-safe and refuses what could read past a bar: Pine or AmenoScript says how the engine tells the two apart and what changes. Strict Pine refuses every addition with Pine v6 strict (line N), and the list of additions includes syntax TradingView rejects, such as x == na and a literal / 0, which run here as AmenoScript.
Where it matches, and how that's held
TradingView is the ground truth here, not our own tests. Where the two differ, the engine is fixed and the test with it, unless a row below says the difference is meant. These parts are held to output captured from TradingView, on all of the terminal's engines:
| Area | Held to |
|---|---|
barstate.* on history, the forming bar and live updates | A live probe on a one-minute chart |
ta.* called in a branch, and over na gaps | Per-family probes, every value |
math.exp, log, log10, pow and the trig functions | Ports of the routines TradingView itself runs. Every exp, log and log10 value read off TradingView matches to the bit |
Constant folding: 0.1 + 0.2 reads 0.3, 2.0 / 15 reads 0.1333333333333333 | The compiler's own folded values |
Compares within 1e-10, x / 0, infinities in each na test and in str.tostring | Probes of each gate |
color.from_gradient, table cells and their defaults | Probes and captured tables |
| Session schedules, holidays and early closes for captured symbols | Captured time_close rows |
| The strategy emulator: fills, exits, margin, the report | Captured trade lists and reports |
| The built-in indicators | What TradingView draws for each on INDEX:BTCUSD daily, or its manual where nothing was captured |
Different on purpose
These read differently by design, and stay that way:
| What | TradingView | Here | Why |
|---|---|---|---|
| A request for a symbol that can't be loaded | Stops the script, unless ignore_invalid_symbol = true | Reads na, with a warning | A feed that failed isn't an error in your script |
| Another symbol's bar in bar replay | Hands over the whole bar while the chart's bar forms | Shows only what was known at the replay's moment | The whole bar would leak the future |
varip in bar replay | Keeps its value across steps | Acts as var, so a step draws what a jump to the same time draws | A replay reads the same however you reach a moment |
A company's quarter and a CPI print in request.financial and request.economic | Dated at the quarter's end or the month after, in today's revisions | Dated at the filing and at the release | The earlier date would read a value before it was public |
alert() and alertcondition() | Fire from an alert set on the chart | Fire only from a rule in the Alerts pane, never from a chart's run (Alerts) | A rule runs on closed bars on the terminal's server, whether or not a page is open |
| An AmenoScript text | No such dialect | Runs leak-safe: lookahead_on, varip, calc_on_every_tick and the rest are refused, even with [1] | Leak-safe AmenoScript |
A Pine text hears each leak-safe finding as a warning and runs as TradingView runs it. See what a run sees.
Different, and open
These differ from TradingView and aren't meant to. Each is a bug in our engine until it's fixed, and the guide page that covers it says how to work around it.
| What | TradingView | Here |
|---|---|---|
str.replace(source, target, replacement, occurrence) | Replaces the nth match | Ignores occurrence and replaces the first (Strings) |
str.format_time with EEE, or SSS | A day name; milliseconds | EEE comes back as typed; SSS writes nine digits |
session.ismarket, .ispremarket, .ispostmarket, .isfirstbar, .islastbar | Follow the session | ismarket is always true and the rest always false |
chart.left_visible_bar_time, .right_visible_bar_time | The visible range | Always 0 |
chart.bg_color, chart.fg_color | The chart's colours | Fixed at #0F1623 and #E2E8F0 in every theme |
request.security(..., currency = ...), request.currency_rate() | Converts | Converts nothing, with a warning; currency_rate reads na unless both currencies are one |
request.seed, request.quandl, request.footprint, footprint.*, volume_row.* | Data | Read na |
== and != beside < or > | Bind more loosely, so a > b == c > d compares two bools | Bind as tightly, so it misparses: add parentheses (Operators) |
x = for ..., x = while ... | A loop's last value | A syntax error |
| An enum value compared with a string or another enum | Refused | Compares by its title: E.a == "Up" can be true |
for i = 0 to n by 0, or a negative step | Stops with an error | A negative step runs by its size; 0 runs no pass |
A table cell with no text_size | size.auto | size.normal |
calc_on_every_tick with process_orders_on_close on a live bar | Keeps a fill through the bar's later updates | The next update drops it |
array.slice | A view: a change to the slice shows in the original | A copy, one level deep (array.slice) |
| Placeholders in an alert's message | The full set, plot_0 and the strategy's among them, in alertcondition() | A shorter list, in alert() too; any other stays as typed (Placeholders) |
display.pine_screener | Shows the plot in TradingView's screener | Does nothing: the Screener lists every plot by its title (Plots) |
export const in a library | Exports the constant | Doesn't parse: the library stops with Expected '(' here (Libraries) |
A value that should match and doesn't
If a TradingView script reads differently here and the difference isn't on this page, it's a bug. The strategy emulator keeps its own list in Strategy emulator: differences.
What runs here that TradingView refuses
The engine accepts some text that TradingView refuses, when it compiles or when it runs. A script that runs here can therefore fail there, so check one you mean to publish on TradingView before you share it.
- Qualifiers. Where TradingView refuses a
seriesvalue in a place that needssimple, such as aserieslength, the run gives aqualifier:warning and goes on. A declared qualifier isn't checked:const float x = closeruns. See qualifiers. - Layout. A script with no declaration, or two, runs. So do a block indented 2 spaces, a stray indented line after a full statement, a
returnstatement and a triple-quoted string. See script structure. - History.
close[-1]reads na here, where TradingView stops the script when it runs.5[1]reads 5, where TradingView refuses it when it compiles.p.price[1]reads na, where TradingView refuses it when it compiles and asks for(p[1]).price. See history. - Types. A reassignment can change a variable's type, and
int n = 1.5keeps 1.5. See types. - Strings.
"a" + 1joins asa1. See strings. - Arguments. A plain argument after a named one is dropped without a word, so
f(a = 1, 2)passes onlya. See parameters and arguments. - Libraries. An importer can call a library function that has no
export. See libraries. - na on a bool.
na()andnz()take a bool, which v6 refuses, andna()can read true for a bool that every condition reads as false. See the bool. - Plot calls.
hline()takes a series price, andalertcondition()runs in a local scope with only a warning.
A field of an object that is na reads na here, with no error. Test na(obj) before you read one, so a missing object can't pass unnoticed on either platform. See Types and enums.
Write scope TradingView's way
TradingView refuses each of these when it compiles a script. Write them its way:
| Don't write | Write instead |
|---|---|
:= on a top-level variable inside a function | Return the new value and assign it where you call the function. See functions and outer variables. |
plot(), hline(), fill(), bgcolor() or another plot-family call inside a function | Plot at the top level, cond ? value : na for some bars only. See what a function can't do. |
| A function declared inside another | Declare each function at the top level. |
| A name read after the block or function that declared it | Declare the variable before the block and change it inside with :=. See scope. |
Limits that differ
| Limit | TradingView | Here |
|---|---|---|
| Run time | A script past 40 seconds stops (RE10110) | No limit |
| A loop's passes | Bounded by time | 100,000, then the loop ends early with no error |
| History | A read past the buffer stops unless max_bars_back makes room | Any depth the chart has; max_bars_back() does nothing |
| Plots | 64 | No cap |
max_labels_count and its kin | At most 500 | Any number |
| A matrix index past the edge | Stops the script | Reads na |
| Keys in a map | 50,000 | No limit |
| Call depth | No recursion | 64, for AmenoScript's recursion |
A heavy script that runs here can stop on TradingView for time. Performance shows how to keep one fast.
What does nothing here
These calls and arguments are accepted, so a script that uses them runs, and they have no effect:
| Accepted | What happens |
|---|---|
log.info(), log.warning(), log.error() | Nothing: there is no Pine Logs pane. See debugging |
max_bars_back() | Nothing: history has no limit |
dynamic_requests = false | Not enforced |
An input's active argument | The input stays active |