Pine Script® v6 has landed

Dec 10, 2024

Today, we are happy to announce the release of Pine Script® v6! This upgraded version of our trader-focused programming language includes a variety of optimizations and long-requested feature enhancements, offering greater efficiency, and utility to Pine Script® programmers, setting the stage to take the language to new heights.

This post outlines a few of the most notable upgrades in Pine v6. See our Release notes to learn more about what’s new in v6 and to stay up-to-date on future improvements.

v6 conversion tool

As with previous version changes, the upgrades included in Pine v6 do not affect personal or published scripts written in earlier Pine versions. All new features from this point onward will be implemented exclusively in the latest Pine version, so we recommend converting your scripts to v6 if you want to access new features. The easiest method is to use our new v6 conversion tool, which you can enable by selecting “Convert code to v6” from the Pine Editor’s “Manage script” menu.

Note that not all scripts can be converted to v6 automatically, and in some cases, manual edits are necessary to ensure the converted script works as expected. If you encounter issues with automatic conversion or prefer to convert your scripts to v6 manually, see our handy Migration guide.

Dynamic requests

TradingView provides access to tens of thousands of symbols for tradable instruments, financial metrics, and economic indicators from around the globe. The request.*() family of functions allows Pine scripts to retrieve data for any available symbol on different timeframes, irrespective of the symbol and timeframe used by the chart.

These functions are powerful utilities with numerous use cases. However, they previously had a significant limitation: they required using “simple string” values to specify the symbol and timeframe of the request, meaning the context had to be known on the first bar and could not change afterward. Additionally, all request.*() calls were forced to execute strictly in the script’s global scope. In other words, any single request.*() instance in the code could fetch data for only one symbol and timeframe, and no request.*() calls were allowed inside loops, conditional structures, or exported library functions.

In Pine Script® v6, we’ve removed these limitations. Now, scripts can use “series string” values to define the context of any request.*() call. In addition, request.*() calls are now allowed inside local scopes. With these changes, you can calculate or modify symbols on any historical bar and request their data dynamically, create collections of symbols and fetch their data within loops, and do many other things with request.*() functions that were previously not possible. See the Dynamic requests section of our User Manual to learn more.

For an example of what you can do with dynamic requests, check out the inner workings of the built-in Performance indicator. It splits comma-separated lists of symbol and timeframe strings into arrays, then calls request.security() dynamically inside loops to fetch values from each dataset. In the past, a script like this would have required multiple input.symbol() and input.timeframe() calls, and each symbol-timeframe combination would have required a separate request.security() call in the code:

For additional reference, check out these scripts published by the TradingView account, which also utilize dynamic requests to fetch data from other contexts.

  • Forex Heatmap. This indicator creates ticker IDs for currency pair combinations based on a user-specified list of currency codes. It dynamically requests data for each pair combination within loops, and then it uses the data to populate a color-coded table.
  • Ticker Tape. This indicator creates an array of ticker IDs from a user-defined list of symbols. It dynamically requests price and daily change information for each ticker ID from the array within a loop, then uses the data to update a rotating “tape” display.
  • LibraryCOT. Previously, this library only provided tools to create ticker IDs for requesting CFTC Commitment of Traders (COT) data because libraries could not export functions containing request.*() calls. With dynamic requests, this limitation no longer applies. The library now exports a requestCommitmentOfTraders() function that calls request.security() internally to retrieve COT data directly, providing more convenience and versatility to programmers.

Additionally, all CFTC report codes were previously held inside switch statements to return “simple” values, significantly limiting the tickers available for request. With dynamic requests, “simple string” ticker IDs are no longer required, allowing the library to store report codes in a map, and provide support for more symbols.

Boolean optimization

One of the most noteworthy improvements in Pine Script® v6 may not be apparent on the surface, but you will likely notice a difference in code efficiency. We’ve reworked the internal implementation of “bool” values in Pine, and we’ve introduced short-circuit (or “lazy”) evaluation, allowing and and or operations to stop evaluating further expressions when they are not required to determine the result.

These changes improve the performance of most scripts on TradingView. The difference in efficiency is especially noticeable with relatively large scripts that rely heavily on conditions and use many “bool” values, as we confirmed in our tests on some of the most popular open-source Community scripts.

As a bonus, lazy “bool” evaluation often allows for cleaner, more concise code. For example, if you have a condition that relies on items from an array, you may have to check the array’s size to ensure the item’s index exists, as the script will stop and raise an error if the index is out of bounds. Pine v6, with its lazy evaluation, allows you to create a single conditional expression that checks the array before attempting to access an element, which was not possible in v5.

//@version=6
indicator("Lazy evaluation demo")

//@variable A "bool" array without a fixed size.
array<bool> myArray = array.new<bool>()

// Push a new value into `myArray` when the `close` is above the `open`.
if close > open
   myArray.push(true)

// Line 13 causes an error in v5 because `myArray.first()` always executes, even if the first expression is `false`.
// It works in v6 though because `myArray.first()` executes only if the first expression evaluates to `true`.
if myArray.size() != 0 and myArray.first()
   label.new(bar_index, high, "Test")

Text size and formatting

All drawing types that display text (boxes, labels, and tables) can now use text sizes specified in typographic points — the same points used in standard text editors. Previously, you would have to choose between arbitrary size.* constants, such as size.large (24) and size.huge (36). Now, with the new typographic point specification, you can ensure the text size is exactly how you want it. You can even create massive text sizes that were impossible to achieve in previous Pine versions.

Additionally, we’ve introduced a new text_formatting parameter for these drawing types, which you can use to make the text italicized, bold, or both.

//@version=6
indicator("Text size showcase", overlay = true)

var t = table.new(position.bottom_center, 1, 2, bgcolor = color.yellow, frame_color = color.black, frame_width = 1)

if barstate.islastconfirmedhistory
    t.cell(0, 0, "text_size = size.huge", text_size = size.huge)
    t.cell(0, 1, "text_size = 60, bold & italicized", text_size = 60, text_formatting = text.format_bold + text.format_italic)

Strategy order trimming

Active strategy script users might know that in Pine v5, a strategy can simulate up to 9000 trades before halting its calculations and raising an error, unless you’re using Deep Backtesting mode. This limitation is especially inconvenient for strategies that simulate frequent trades and create alert triggers.

In Pine Script® v6, strategies no longer stop calculating or raise an error after reaching the 9000 trade limit. Instead, the strategy trims the oldest orders to make space for the new ones. The trimmed orders do not appear in the Strategy Tester, but the strategy continues its calculations without issue. To check the trade index of the oldest non-trimmed order, you can use the new strategy.closedtrades.first_index variable. The index is usable as the trade_num argument in strategy.closedtrades.*() function calls.

Negative array indices

In Pine v6, the array.get(), array.set(), array.insert(), and array.remove() functions can now accept negative index arguments to reference items starting from the end of an array, offering a more concise, convenient way to reference array elements in reverse order. For example, the call array.get(myArray, -2) retrieves the second to last element in myArray, which is equivalent to array.get(myArray, array.size(myArray) – 2).

To stay updated on the latest improvements to the Pine Script® experience, keep an eye on the User Manual’s Release notes — its v6 section even includes some additional changes that did not make it into this blog post.

We hope you find these features as useful as we think they’ll be, and please do keep sending us your feedback and suggestions so we can make the platform the best it can be. We build TradingView for you, and we’re always keen to hear your thoughts.

— Team TradingView

Look first Then leap

TradingView is built for you, so make sure you're getting the most of our awesome features
Launch Chart