Limitations — Pine Script™ v5 User Manual documentation (2024)

Introduction

As is mentioned in our Welcome page:

Because each script uses computational resources in the cloud, we must impose limits in order to share these resources fairly among our users.We strive to set as few limits as possible, but will of course have to implement as many as needed for the platform to run smoothly.Limitations apply to the amount of data requested from additional symbols, execution time, memory usage and script size.

If you develop complex scripts using Pine Script™, sooner or later you will run into some of the limitations we impose.This section provides you with an overview of the limitations that you may encounter.There are currently no means for Pine Script™ programmers to get data on the resources consumed by their scripts.We hope this will change in the future.

In the meantime, when you are considering large projects, it is safest to make a proof of conceptin order to assess the probability of your script running into limitations later in your project.

Below, we describe the limits imposed in the Pine Script™ environment.

Time

Script compilation

Scripts must compile before they are executed on charts. Compilation occurs when you save a script from the Pine Editor or when you add a script to the chart.A two-minute limit is imposed on compilation time, which will depend on the size and complexity of your script,and whether or not a cached version of a previous compilation is available.When a compile exceeds the two-minute limit, a warning is issued.Heed that warning by shortening your script because after three consecutives warnings a one-hour ban on compilation attempts is enforced.The first thing to consider when optimizing code is to avoid repetitions by using functions to encapsulate oft-used segments,and call functions instead of repeating code.

Script execution

Once a script is compiled it can be executed.See the Events triggering the execution of a script for a list of the events triggering the execution of a script.The time allotted for the script to execute on all bars of a dataset varies with account types. The limit is 20 seconds for basic accounts, 40 for others.

Loop execution

The execution time for any loop on any single bar is limited to 500 milliseconds.The outer loop of embedded loops counts as one loop, so it will time out first.Keep in mind that even though a loop may execute under the 500 ms time limit on a given bar,the time it takes to execute on all the dataset’s bars may nonetheless cause your script to exceed the total execution time limit.For example, the limit on total execution time will make it impossible for you script to execute a 400 ms loop on each bar of a 20,000-bar datasetbecause your script would then need 8000 seconds to execute.

Chart visuals

Plot limits

A maximum of 64 plot counts are allowed per script. The functions that generate plot counts are:

  • plot()
  • plotarrow()
  • plotbar()
  • plotcandle()
  • plotchar()
  • plotshape()
  • alertcondition()
  • bgcolor()
  • fill(), but only if its color is of the series form.

The following functions do not generate plot counts:

  • hline()
  • line.new()
  • label.new()
  • table.new()
  • box.new()

One function call can generate up to seven plot counts, depending on the function and how it is called.When your script exceeds the maximum of 64 plot counts, the runtime error message will display the plot count generated by your script.Once you reach that point, you can determine how many plot counts a function call generates by commenting it out in a script.As long as your script still throws an error, you will be able to see how the actual plot count decreases after you have commented out a line.

The following example shows different function calls and the number of plot counts each one will generate:

//@version=5indicator("Plot count example")bool isUp = close > opencolor isUpColor = isUp ? color.green : color.redbool isDn = not isUpcolor isDnColor = isDn ? color.red : color.green// Uses one plot count each.p1 = plot(close, color = color.white)p2 = plot(open, color = na)// Uses two plot counts for the `close` and `color` series.plot(close, color = isUpColor)// Uses one plot count for the `close` series.plotarrow(close, colorup = color.green, colordown = color.red)// Uses two plot counts for the `close` and `colorup` series.plotarrow(close, colorup = isUpColor)// Uses three plot counts for the `close`, `colorup`, and the `colordown` series.plotarrow(close - open, colorup = isUpColor, colordown = isDnColor)// Uses four plot counts for the `open`, `high`, `low`, and `close` series.plotbar(open, high, low, close, color = color.white)// Uses five plot counts for the `open`, `high`, `low`, `close`, and `color` series.plotbar(open, high, low, close, color = isUpColor)// Uses four plot counts for the `open`, `high`, `low`, and `close` series.plotcandle(open, high, low, close, color = color.white, wickcolor = color.white, bordercolor = color.purple)// Uses five plot counts for the `open`, `high`, `low`, `close`, and `color` series.plotcandle(open, high, low, close, color = isUpColor, wickcolor = color.white, bordercolor = color.purple)// Uses six plot counts for the `open`, `high`, `low`, `close`, `color`, and `wickcolor` series.plotcandle(open, high, low, close, color = isUpColor, wickcolor = isUpColor , bordercolor = color.purple)// Uses seven plot counts for the `open`, `high`, `low`, `close`, `color`, `wickcolor`, and `bordercolor` series.plotcandle(open, high, low, close, color = isUpColor, wickcolor = isUpColor , bordercolor = isUp ? color.lime : color.maroon)// Uses one plot count for the `close` series.plotchar(close, color = color.white, text = "|", textcolor = color.white)// Uses two plot counts for the `close`` and `color` series.plotchar(close, color = isUpColor, text = "—", textcolor = color.white)// Uses three plot counts for the `close`, `color`, and `textcolor` series.plotchar(close, color = isUpColor, text = "O", textcolor = isUp ? color.yellow : color.white)// Uses one plot count for the `close` series.plotshape(close, color = color.white, textcolor = color.white)// Uses two plot counts for the `close` and `color` series.plotshape(close, color = isUpColor, textcolor = color.white)// Uses three plot counts for the `close`, `color`, and `textcolor` series.plotshape(close, color = isUpColor, textcolor = isUp ? color.yellow : color.white)// Uses one plot count.alertcondition(close > open, "close > open", "Up bar alert")// Uses one plot count.bgcolor(isUp ? color.yellow : color.white)// Uses one plot count for the `color` series.fill(p1, p2, color = isUpColor)

This example generates a plot count of 56. If we were to add two more instances of the last call toplotcandle(),the script would throw an error stating that the script now uses 70 plot counts, as each additional call toplotcandle()generates seven plot counts, and 56 + (7 * 2) is 70.

Line, box, polyline, and label limits

Contrary to plots, which can cover the chart’s entire dataset, scripts will only show the last 50lines, boxes, polylines,and labels on the chart by default. One can increase the maximum number for each of thesedrawing types via the max_lines_count, max_boxes_count, max_polylines_count,and max_labels_count parameters of the script’sindicator() orstrategy() declaration statement. The maximum number ofline,box, andlabel IDs is 500, and the maximum number ofpolyline IDs is 100.

In this example, we set the maximum number of recent labels shown on the chart to 100:

//@version=5indicator("Label limits example", max_labels_count = 100, overlay = true)label.new(bar_index, high, str.tostring(high, format.mintick))

It’s important to note when setting any of a drawing object’s properties tona that its ID still exists and thus contributes to ascript’s drawing totals. To demonstrate this behavior, the following script draws a “Buy” and “Sell”label on each bar, with x values determined by thelongCondition and shortCondition variables.

The “Buy” label’s x value is na when the bar index is even,and the “Sell” label’s x value is na when the bar index is odd.Although the max_labels_count is 10 in this example, we can see that the script displays fewer than 10 labelson the chart since the ones with na values also count toward the total:

Limitations — Pine Script™ v5 User Manual documentation (1)

//@version=5// Approximate maximum number of label drawingsMAX_LABELS = 10indicator("labels with na", overlay = false, max_labels_count = MAX_LABELS)// Add background color for the last MAX_LABELS bars.bgcolor(bar_index > last_bar_index - MAX_LABELS ? color.new(color.green, 80) : na)longCondition = bar_index % 2 != 0shortCondition = bar_index % 2 == 0// Add "Buy" and "Sell" labels on each new bar.label.new(longCondition ? bar_index : na, 0, text = "Buy", color = color.new(color.green, 0), style = label.style_label_up)label.new(shortCondition ? bar_index : na, 0, text = "Sell", color = color.new(color.red, 0), style = label.style_label_down)plot(longCondition ? 1 : 0)plot(shortCondition ? 1 : 0)

To display the desired number of labels, we must eliminate label drawings we don’t want to show rather than setting their properties tona. The example below uses anif structure to conditionally draw the “Buy” and “Sell” labels,preventing the script from creating new label IDs when it isn’t necessary:

Limitations — Pine Script™ v5 User Manual documentation (2)

//@version=5// Approximate maximum number of label drawingsMAX_LABELS = 10indicator("conditional labels", overlay = false, max_labels_count = MAX_LABELS)// Add background color for the last MAX_LABELS bars.bgcolor(bar_index > last_bar_index - MAX_LABELS ? color.new(color.green, 80) : na)longCondition = bar_index % 2 != 0shortCondition = bar_index % 2 == 0// Add a "Buy" label when `longCondition` is true.if longCondition label.new(bar_index, 0, text = "Buy", color = color.new(color.green, 0), style = label.style_label_up)// Add a "Sell" label when `shortCondition` is true.if shortCondition label.new(bar_index, 0, text = "Sell", color = color.new(color.red, 0), style = label.style_label_down)plot(longCondition ? 1 : 0)plot(shortCondition ? 1 : 0)

Table limits

Scripts can display a maximum of nine tables on the chart, one for each of the possible locations:position.bottom_center,position.bottom_left,position.bottom_right,position.middle_center,position.middle_left,position.middle_right,position.top_center,position.top_left,and position.top_right.When attempting to place two tables in the same location, only the newest instance will show on the chart.

`request.*()` calls

Number of calls

A script cannot contain more than 40 calls to functions in the request.() namespace. All instances of thesefunctions count toward this limit, even when contained within local blocks of user-defined functionsthat aren’t utilized by the script’s main logic. This limitation applies to all functions discussed in theOther timeframes and data page, including:

  • request.security()
  • request.security_lower_tf()
  • request.currency_rate()
  • request.dividends()
  • request.splits()
  • request.earnings()
  • request.quandl()
  • request.financial()
  • request.economic()
  • request.seed()

Intrabars

Scripts can retrieve up to the most recent 100,000 intrabars (lower-timeframe bars) via therequest.security() orrequest.security_lower_tf()functions.

The number of bars on the chart’s timeframe covered by 100,000 intrabars varies with the number ofintrabars each chart bar contains. For example, requesting data from the 1-minute timeframe while runningthe script on a 60-minute chart means each chart bar can contain up to 60 intrabars. In this case,the minimum number of chart bars covered by the intrabar request is 1,666, as 100,000 / 60 = 1,666.67.It’s important to note, however, that a provider may not report data for every minute within an hour.Therefore, such a request may cover more chart bars, depending on the available data.

Tuple element limit

All the request.*() function calls in a script taken together cannot return more than 127 tuple elements.When the combined tuple size of all request.*() calls will exceed 127 elements, one can instead utilizeuser-defined types (UDTs) to request a greater number of values.

The example below outlines this limitation and the way to work around it. The firstrequest.security() call representsusing a tuple with 128 elements as the expression argument. Since the number of elements is greater than 127,it would result in an error.

To avoid the error, we can use those same values as fields within anobject of a UDT and pass its ID to theexpression instead:

//@version=5indicator("Tuple element limit")s1 = closes2 = close * 2...s128 = close * 128// Causes an error.[v1, v2, v3, ..., v128] = request.security(syminfo.tickerid, "1D", [s1, s2, s3, ..., s128])// Works fine:type myType float v1 float v2 float v3 ... float v128myObj = request.security(syminfo.tickerid, "1D", myType.new(s1, s2, s3, ..., s128))
Note that:
  • This example outlines a scenario where the script tries to evaluate 128 tuple elements in a singlerequest.security() call.The same limitation applies if we were to split the tuple request across multiple calls. For example,two request.security() callsthat each retrieve a tuple with 64 elements will also cause an error.

Script size and memory

Compiled tokens

Before the execution of a script, the compiler translates it into a tokenized Intermediate Language (IL).Using an IL allows Pine Script™ to accommodate larger scripts by applying various memory and performance optimizations.The compiler determines the size of a script based on the number of tokens in its IL form, not the number ofcharacters or lines in the code viewable in the Pine Editor.

The compiled form of each indicator, strategy, and library script is limited to 71,000 tokens. When a script imports libraries,the total number of tokens from all imported libraries cannot exceed 1 million. There is no way to inspect a script’s compiled form,nor its IL token count. As such, you will only know your script exceeds the size limit when the compiler reaches it.

In most cases, a script’s compiled size will likely not reach the limit. However, if a compiled script does reach the token limit,the most effective ways to decrease compiled tokens are to reduce repetitive code, encapsulate redundant calls within functions,and utilize libraries when possible.

It’s important to note that the compilation process omits any unused variables, functions, types, etc. fromthe final IL form, where “unused” refers to anything that does not affect the script’s outputs.This optimization prevents superfluous elements in the code from contributing to the script’s IL token count.

For example, the script below declares a user-defined type and auser-defined method and defines a sequence of calls using them:

//@version=5indicator("My Script")plot(close)type myType float field = 10.0method m(array<myType> a, myType v) => a.push(v)var arr = array.new<myType>()arr.push(myType.new(25))arr.m(myType.new())

Despite the inclusion of array.new<myType>(),myType.new(), and arr.m() calls in the script, the only thing actually output by the script is plot(close).The rest of the code does not affect the output. Therefore, the compiled form of this script will have the same number of tokens as:

//@version=5indicator("My Script")plot(close)

Variables per scope

Scripts can contain up to 1,000 variables in each of its scopes. Pine scripts always contain one global scope,represented by non-indented code, and they may contain zero or more local scopes. Local scopes are sections ofindented code representing procedures executed within functions andmethods, as well asif,switch,for,for…in, andwhile structures, which allow for one or morelocal blocks. Each local block counts as one local scope.

The branches of a conditional expression using the?: ternary operator do not count as local blocks.

Scope count

The total number of scopes in a script, including its global scope and each local scopefrom the user-defined functions, methods,conditional structures, or loops it uses, cannot exceed 500.

It’s important to note that the request.security(),request.security_lower_tf(), andrequest.seed() functionsduplicate the scopes required to evaluate the values of their expression argument in another context.The scopes produced by each call to these request.*() functions also count toward the script’s scope limit.

For example, suppose we created a script with a global variable that depends on the local scopes of 250if structures. The total scope count for this script is251 (1 global scope + 250 local scopes):

//@version=5indicator("Scopes demo")var x = 0if close > 0 x += 0if close > 1 x += 1// ... Repeat this `if close > n` pattern until `n = 249`.if close > 249 x += 249plot(x)

Since the total number of scopes is within the limit, it will compile successfully.Now, suppose we call request.security()to evaluate the value of x from another context and plot its value as well. In this case,it will effectively double the script’s scope count since the value of x depends on all the script’s scopes:

//@version=5indicator("Scopes demo")var x = 0if close > 0 x += 0if close > 1 x += 1// ... Repeat this `if close > n` pattern until `n = 249`.if close > 249 x += 249plot(x)plot(request.security(syminfo.tickerid, "1D", x) // Causes compilation error since the scope count is now 502.

We can resolve this issue by encapsulating the if blockswithin a user-defined function, as the scope of a function counts as one embeddedscope:

//@version=5indicator("Scopes demo")f() => var x = 0 if close > 0 x += 0 if close > 1 x += 1 // ... Repeat this `if close > n` pattern until `n = 249`. if close > 249 x += 249plot(f())plot(request.security(syminfo.tickerid, "1D", f()) // No compilation error.

Collections

Pine Script™ collections (arrays, matrices,and maps) can have a maximum of 100,000 elements. Each key-value pair in a mapcontains two elements, meaning maps can contain a maximum of 50,000 key-value pairs.

Other limitations

Maximum bars back

References to past values using the[]history-referencing operator are dependent on the size of the historical buffer maintained by the Pine Script™ runtime, which is limited to a maximum of 5000 bars.This Help Center pagediscusses the historical buffer and how to change its size using either the max_bars_back parameter or themax_bars_back() function.

Maximum bars forward

When positioning drawings using xloc.bar_index, it is possible to use bar index values greater than that of the current bar as x coordinates.A maximum of 500 bars in the future can be referenced.

This example shows how we use the maxval parameter in ourinput.int()function call to cap the user-defined number of bars forward we draw a projection line so that it never exceeds the limit:

//@version=5indicator("Max bars forward example", overlay = true)// This function draws a `line` using bar index x-coordinates.drawLine(bar1, y1, bar2, y2) => // Only execute this code on the last bar. if barstate.islast // Create the line only the first time this function is executed on the last bar. var line lin = line.new(bar1, y1, bar2, y2, xloc.bar_index) // Change the line's properties on all script executions on the last bar. line.set_xy1(lin, bar1, y1) line.set_xy2(lin, bar2, y2)// Input determining how many bars forward we draw the `line`.int forwardBarsInput = input.int(10, "Forward Bars to Display", minval = 1, maxval = 500)// Calculate the line's left and right points.int leftBar = bar_index[2]float leftY = high[2]int rightBar = leftBar + forwardBarsInputfloat rightY = leftY + (ta.change(high)[1] * forwardBarsInput)// This function call is executed on all bars, but it only draws the `line` on the last bar.drawLine(leftBar, leftY, rightBar, rightY)

Chart bars

The number of bars appearing on charts is dependent on the amount of historical data available for the chart’s symbol and timeframe,and on the type of account you hold. When the required historical date is available, the minimum number of chart bars is:

  • 40,000 bars for the Ultimate plan.
  • 30,000 bars for the Elite plan.
  • 25,000 bars for the Expert plan.
  • 20,000 bars for the Premium plan.
  • 10,000 bars for Essential and Plus plans.
  • 5000 bars for the Basic plan.

Trade orders in backtesting

A maximum of 9000 orders can be placed when backtesting strategies.When using Deep Backtesting, the limit is 200,000.

Limitations — Pine Script™ v5 User Manual  documentation (2024)

FAQs

What are the limitations of Pinescript? ›

Pine Script™ collections (arrays, matrices, and maps) can have a maximum of 100,000 elements. Each key-value pair in a map contains two elements, meaning maps can contain a maximum of 50,000 key-value pairs.

What is the security limitation in pine script request? ›

The limit for security() calls is 40, but by using functions returning tuples with security(), you can fetch many more values than 40.

What is the limit of labels in Pinescript? ›

label. new() can display a maximum of 500 labels on the chart.

What is Pinescript v5? ›

Pine Script™ is TradingView's programming language. It allows traders to create their own trading tools and run them on our servers.

What is the new limit in Pinescript line? ›

A single script instance can display up to 500 lines, 500 boxes, and 100 polylines.

How useful is Pinescript? ›

It is a powerful tool that enables traders to automate their trading decisions, backtest their ideas, and execute trades directly from the charts. One of the key advantages of Pine Script is its flexibility. Traders can use it to analyze and trade stocks, forex, cryptocurrencies, and other financial instruments.

What is the maximum array size in Pinescript? ›

The size of arrays is limited to 100,000 elements.

What platform is better than TradingView? ›

Other important factors to consider when researching alternatives to TradingView include features and price. The best overall TradingView alternative is eToro. Other similar apps like TradingView are MetaTrader 5, Binance Broker, E*Trade Web Platform, and thinkorswim.

What is the plot limit in Pinescript? ›

Plot count limit

Each script is limited to a maximum plot count of 64.

How do I convert Pinescript version 4 to 5? ›

If you are on Version 4, select the “More” icon (∘∘∘) in the Pine Editor → click on “Convert to v5”. Click “Save” to save the actions you just made.

What is highest function in Pinescript? ›

highest() function returns the highest value from a series of data for a certain number of bars back.

What version of Pine Script does TradingView use? ›

Pine Script™ v5 User Manual.

What are the limitations of description technique? ›

Descriptive research methodologies have several limitations. These studies often lack prior support for hypotheses and do not provide data on potential confounders or other sources of bias. They tend to replicate well-known associations but cannot be used to infer causality.

What are the limitations of steganography project? ›

Steganography has limitations in terms of capacity, resilience, and imperceptibility. It is challenging to develop an efficient steganography system that can handle large amounts of data while maintaining security and hiding information effectively.

What are the limitations of the business cases technique? ›

Common business case weaknesses
  • Weakness 1: Writing the business case with a set solution in mind – this can result in an inappropriate investment that won't fix the 'real' problem.
  • Weakness 2: Poorly defined problems – this can result in limiting and/or warping the best strategic response.
Jan 21, 2019

References

Top Articles
Latest Posts
Article information

Author: Maia Crooks Jr

Last Updated:

Views: 6029

Rating: 4.2 / 5 (43 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Maia Crooks Jr

Birthday: 1997-09-21

Address: 93119 Joseph Street, Peggyfurt, NC 11582

Phone: +2983088926881

Job: Principal Design Liaison

Hobby: Web surfing, Skiing, role-playing games, Sketching, Polo, Sewing, Genealogy

Introduction: My name is Maia Crooks Jr, I am a homely, joyous, shiny, successful, hilarious, thoughtful, joyous person who loves writing and wants to share my knowledge and understanding with you.