Arrays in Pine Script offer a powerful way to store, manipulate, and analyze multiple data points efficiently. They are particularly useful in creating screeners that evaluate multiple securities simultaneously. In this blog, we will explore how arrays work in Pine Script, their key operations, and how they can be leveraged to build a robust screener.
What Are Arrays in Pine Script?
An array is a data structure that allows storing multiple values in a single variable. Pine Script supports arrays of various types, including integers, floats, booleans, and strings. Arrays enable traders to perform calculations on a collection of values without manually defining separate variables for each data point.
Declaring Arrays
To create an array in Pine Script, use:
myArray = array.new_float(0) // Creates an empty float array
Here, array.new_float(0)
initializes an empty array that can later hold floating-point numbers.
Adding Elements to an Array
Use array.push()
to insert elements into an array:
array.push(myArray, 50.5)
array.push(myArray, 75.3)
This appends values to the array dynamically.
Accessing Elements
Retrieve values from an array using array.get()
:
value = array.get(myArray, 0) // Retrieves the first element
Modifying Elements
Modify an existing element using array.set()
:
array.set(myArray, 1, 80.2) // Updates the second element
Removing Elements
Remove the last element from an array with array.pop()
:
lastValue = array.pop(myArray)
Other Useful Operations
array.size(myArray)
: Returns the number of elements.array.clear(myArray)
: Removes all elements.array.sort(myArray, order.asc)
: Sorts the array in ascending order.
Building a Stock Screener Using Arrays
A stock screener identifies securities that meet predefined criteria. Arrays simplify the process of managing multiple stocks dynamically. Below is an example of a simple RSI-based stock screener:
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © algostudio
//@version=6
indicator('NIFTY 40 Screener', overlay=true)
////////////
// INPUTS //
// RSI
rsi_len = input.int( 14, title = "RSI Length", group = "Indicators")
rsi_os = input.float(30, title = "RSI Overbought", group = "Indicators")
rsi_ob = input.float(70, title = "RSI Oversold", group = "Indicators")
col_width = input.float(5, title = "Column Width (%)")
scr_numb = input.int(1, title = "Screen #", tooltip = '1 - rightmost screener', minval = 1)
/////////////
// SYMBOLS //
u01 = input.bool(true, title = "", group = 'Symbols', inline = 's01')
u02 = input.bool(true, title = "", group = 'Symbols', inline = 's02')
u03 = input.bool(true, title = "", group = 'Symbols', inline = 's03')
u04 = input.bool(true, title = "", group = 'Symbols', inline = 's04')
u05 = input.bool(true, title = "", group = 'Symbols', inline = 's05')
u06 = input.bool(true, title = "", group = 'Symbols', inline = 's06')
u07 = input.bool(true, title = "", group = 'Symbols', inline = 's07')
u08 = input.bool(true, title = "", group = 'Symbols', inline = 's08')
u09 = input.bool(true, title = "", group = 'Symbols', inline = 's09')
u10 = input.bool(true, title = "", group = 'Symbols', inline = 's10')
u11 = input.bool(true, title = "", group = 'Symbols', inline = 's11')
u12 = input.bool(true, title = "", group = 'Symbols', inline = 's12')
u13 = input.bool(true, title = "", group = 'Symbols', inline = 's13')
u14 = input.bool(true, title = "", group = 'Symbols', inline = 's14')
u15 = input.bool(true, title = "", group = 'Symbols', inline = 's15')
u16 = input.bool(true, title = "", group = 'Symbols', inline = 's16')
u17 = input.bool(true, title = "", group = 'Symbols', inline = 's17')
u18 = input.bool(true, title = "", group = 'Symbols', inline = 's18')
u19 = input.bool(true, title = "", group = 'Symbols', inline = 's19')
u20 = input.bool(true, title = "", group = 'Symbols', inline = 's20')
u21 = input.bool(true, title = "", group = 'Symbols', inline = 's21')
u22 = input.bool(true, title = "", group = 'Symbols', inline = 's22')
u23 = input.bool(true, title = "", group = 'Symbols', inline = 's23')
u24 = input.bool(true, title = "", group = 'Symbols', inline = 's24')
u25 = input.bool(true, title = "", group = 'Symbols', inline = 's25')
u26 = input.bool(true, title = "", group = 'Symbols', inline = 's26')
u27 = input.bool(true, title = "", group = 'Symbols', inline = 's27')
u28 = input.bool(true, title = "", group = 'Symbols', inline = 's28')
u29 = input.bool(true, title = "", group = 'Symbols', inline = 's29')
u30 = input.bool(true, title = "", group = 'Symbols', inline = 's30')
u31 = input.bool(true, title = "", group = 'Symbols', inline = 's31')
u32 = input.bool(true, title = "", group = 'Symbols', inline = 's32')
u33 = input.bool(true, title = "", group = 'Symbols', inline = 's33')
u34 = input.bool(true, title = "", group = 'Symbols', inline = 's34')
u35 = input.bool(true, title = "", group = 'Symbols', inline = 's35')
u36 = input.bool(true, title = "", group = 'Symbols', inline = 's36')
u37 = input.bool(true, title = "", group = 'Symbols', inline = 's37')
u38 = input.bool(true, title = "", group = 'Symbols', inline = 's38')
u39 = input.bool(true, title = "", group = 'Symbols', inline = 's39')
u40 = input.bool(true, title = "", group = 'Symbols', inline = 's40')
s01 = input.symbol('NSE:ADANIENT', group = 'Symbols', inline = 's01')
s02 = input.symbol('NSE:ADANIPORTS', group = 'Symbols', inline = 's02')
s03 = input.symbol('NSE:APOLLOHOSP', group = 'Symbols', inline = 's03')
s04 = input.symbol('NSE:ASIANPAINT', group = 'Symbols', inline = 's04')
s05 = input.symbol('NSE:AXISBANK', group = 'Symbols', inline = 's05')
s06 = input.symbol('NSE:BAJAJ_AUTO', group = 'Symbols', inline = 's06')
s07 = input.symbol('NSE:BAJFINANCE', group = 'Symbols', inline = 's07')
s08 = input.symbol('NSE:BAJAJFINSV', group = 'Symbols', inline = 's08')
s09 = input.symbol('NSE:BEL', group = 'Symbols', inline = 's09')
s10 = input.symbol('NSE:BPCL', group = 'Symbols', inline = 's10')
s11 = input.symbol('NSE:BHARTIARTL', group = 'Symbols', inline = 's11')
s12 = input.symbol('NSE:BRITANNIA', group = 'Symbols', inline = 's12')
s13 = input.symbol('NSE:CIPLA', group = 'Symbols', inline = 's13')
s14 = input.symbol('NSE:COALINDIA', group = 'Symbols', inline = 's14')
s15 = input.symbol('NSE:DRREDDY', group = 'Symbols', inline = 's15')
s16 = input.symbol('NSE:EICHERMOT', group = 'Symbols', inline = 's16')
s17 = input.symbol('NSE:GRASIM', group = 'Symbols', inline = 's17')
s18 = input.symbol('NSE:HCLTECH', group = 'Symbols', inline = 's18')
s19 = input.symbol('NSE:HDFCBANK', group = 'Symbols', inline = 's19')
s20 = input.symbol('NSE:HDFCLIFE', group = 'Symbols', inline = 's20')
s21 = input.symbol('NSE:HEROMOTOCO', group = 'Symbols', inline = 's21')
s22 = input.symbol('NSE:HINDALCO', group = 'Symbols', inline = 's22')
s23 = input.symbol('NSE:HINDUNILVR', group = 'Symbols', inline = 's23')
s24 = input.symbol('NSE:ICICIBANK', group = 'Symbols', inline = 's24')
s25 = input.symbol('NSE:ITC', group = 'Symbols', inline = 's25')
s26 = input.symbol('NSE:INDUSINDBK', group = 'Symbols', inline = 's26')
s27 = input.symbol('NSE:INFY', group = 'Symbols', inline = 's27')
s28 = input.symbol('NSE:JSWSTEEL', group = 'Symbols', inline = 's28')
s29 = input.symbol('NSE:KOTAKBANK', group = 'Symbols', inline = 's29')
s30 = input.symbol('NSE:LT', group = 'Symbols', inline = 's30')
s31 = input.symbol('NSE:M&M', group = 'Symbols', inline = 's31')
s32 = input.symbol('NSE:MARUTI', group = 'Symbols', inline = 's32')
s33 = input.symbol('NSE:NTPC', group = 'Symbols', inline = 's33')
s34 = input.symbol('NSE:NESTLEIND', group = 'Symbols', inline = 's34')
s35 = input.symbol('NSE:ONGC', group = 'Symbols', inline = 's35')
s36 = input.symbol('NSE:POWERGRID', group = 'Symbols', inline = 's36')
s37 = input.symbol('NSE:RELIANCE', group = 'Symbols', inline = 's37')
s38 = input.symbol('NSE:SBILIFE', group = 'Symbols', inline = 's38')
s39 = input.symbol('NSE:SHRIRAMFIN', group = 'Symbols', inline = 's39')
s40 = input.symbol('NSE:SBIN', group = 'Symbols', inline = 's40')
//////////////////
// CALCULATIONS //
// Get only symbol
only_symbol(s) =>
array.get(str.split(s, ":"), 1)
screener_func() =>
// RSI
rsi = ta.rsi(close, rsi_len)
rsi
// Security call
rsi01 = request.security(s01, timeframe.period, screener_func())
rsi02 = request.security(s02, timeframe.period, screener_func())
rsi03 = request.security(s03, timeframe.period, screener_func())
rsi04 = request.security(s04, timeframe.period, screener_func())
rsi05 = request.security(s05, timeframe.period, screener_func())
rsi06 = request.security(s06, timeframe.period, screener_func())
rsi07 = request.security(s07, timeframe.period, screener_func())
rsi08 = request.security(s08, timeframe.period, screener_func())
rsi09 = request.security(s09, timeframe.period, screener_func())
rsi10 = request.security(s10, timeframe.period, screener_func())
rsi11 = request.security(s11, timeframe.period, screener_func())
rsi12 = request.security(s12, timeframe.period, screener_func())
rsi13 = request.security(s13, timeframe.period, screener_func())
rsi14 = request.security(s14, timeframe.period, screener_func())
rsi15 = request.security(s15, timeframe.period, screener_func())
rsi16 = request.security(s16, timeframe.period, screener_func())
rsi17 = request.security(s17, timeframe.period, screener_func())
rsi18 = request.security(s18, timeframe.period, screener_func())
rsi19 = request.security(s19, timeframe.period, screener_func())
rsi20 = request.security(s20, timeframe.period, screener_func())
rsi21 = request.security(s21, timeframe.period, screener_func())
rsi22 = request.security(s22, timeframe.period, screener_func())
rsi23 = request.security(s23, timeframe.period, screener_func())
rsi24 = request.security(s24, timeframe.period, screener_func())
rsi25 = request.security(s25, timeframe.period, screener_func())
rsi26 = request.security(s26, timeframe.period, screener_func())
rsi27 = request.security(s27, timeframe.period, screener_func())
rsi28 = request.security(s28, timeframe.period, screener_func())
rsi29 = request.security(s29, timeframe.period, screener_func())
rsi30 = request.security(s30, timeframe.period, screener_func())
rsi31 = request.security(s31, timeframe.period, screener_func())
rsi32 = request.security(s32, timeframe.period, screener_func())
rsi33 = request.security(s33, timeframe.period, screener_func())
rsi34 = request.security(s34, timeframe.period, screener_func())
rsi35 = request.security(s35, timeframe.period, screener_func())
rsi36 = request.security(s36, timeframe.period, screener_func())
rsi37 = request.security(s37, timeframe.period, screener_func())
rsi38 = request.security(s38, timeframe.period, screener_func())
rsi39 = request.security(s39, timeframe.period, screener_func())
rsi40 = request.security(s40, timeframe.period, screener_func())
////////////
// ARRAYS //
s_arr = array.new_string(0)
u_arr = array.new_bool(0)
rsi_arr = array.new_float(0)
// Add Symbols
array.push(s_arr, only_symbol(s01))
array.push(s_arr, only_symbol(s02))
array.push(s_arr, only_symbol(s03))
array.push(s_arr, only_symbol(s04))
array.push(s_arr, only_symbol(s05))
array.push(s_arr, only_symbol(s06))
array.push(s_arr, only_symbol(s07))
array.push(s_arr, only_symbol(s08))
array.push(s_arr, only_symbol(s09))
array.push(s_arr, only_symbol(s10))
array.push(s_arr, only_symbol(s11))
array.push(s_arr, only_symbol(s12))
array.push(s_arr, only_symbol(s13))
array.push(s_arr, only_symbol(s14))
array.push(s_arr, only_symbol(s15))
array.push(s_arr, only_symbol(s16))
array.push(s_arr, only_symbol(s17))
array.push(s_arr, only_symbol(s18))
array.push(s_arr, only_symbol(s19))
array.push(s_arr, only_symbol(s20))
array.push(s_arr, only_symbol(s21))
array.push(s_arr, only_symbol(s22))
array.push(s_arr, only_symbol(s23))
array.push(s_arr, only_symbol(s24))
array.push(s_arr, only_symbol(s25))
array.push(s_arr, only_symbol(s26))
array.push(s_arr, only_symbol(s27))
array.push(s_arr, only_symbol(s28))
array.push(s_arr, only_symbol(s29))
array.push(s_arr, only_symbol(s30))
array.push(s_arr, only_symbol(s31))
array.push(s_arr, only_symbol(s32))
array.push(s_arr, only_symbol(s33))
array.push(s_arr, only_symbol(s34))
array.push(s_arr, only_symbol(s35))
array.push(s_arr, only_symbol(s36))
array.push(s_arr, only_symbol(s37))
array.push(s_arr, only_symbol(s38))
array.push(s_arr, only_symbol(s39))
array.push(s_arr, only_symbol(s40))
// FLAGS
array.push(u_arr, u01)
array.push(u_arr, u02)
array.push(u_arr, u03)
array.push(u_arr, u04)
array.push(u_arr, u05)
array.push(u_arr, u06)
array.push(u_arr, u07)
array.push(u_arr, u08)
array.push(u_arr, u09)
array.push(u_arr, u10)
array.push(u_arr, u11)
array.push(u_arr, u12)
array.push(u_arr, u13)
array.push(u_arr, u14)
array.push(u_arr, u15)
array.push(u_arr, u16)
array.push(u_arr, u17)
array.push(u_arr, u18)
array.push(u_arr, u19)
array.push(u_arr, u20)
array.push(u_arr, u21)
array.push(u_arr, u22)
array.push(u_arr, u23)
array.push(u_arr, u24)
array.push(u_arr, u25)
array.push(u_arr, u26)
array.push(u_arr, u27)
array.push(u_arr, u28)
array.push(u_arr, u29)
array.push(u_arr, u30)
array.push(u_arr, u31)
array.push(u_arr, u32)
array.push(u_arr, u33)
array.push(u_arr, u34)
array.push(u_arr, u35)
array.push(u_arr, u36)
array.push(u_arr, u37)
array.push(u_arr, u38)
array.push(u_arr, u39)
array.push(u_arr, u40)
// RSI
array.push(rsi_arr, rsi01)
array.push(rsi_arr, rsi02)
array.push(rsi_arr, rsi03)
array.push(rsi_arr, rsi04)
array.push(rsi_arr, rsi05)
array.push(rsi_arr, rsi06)
array.push(rsi_arr, rsi07)
array.push(rsi_arr, rsi08)
array.push(rsi_arr, rsi09)
array.push(rsi_arr, rsi10)
array.push(rsi_arr, rsi11)
array.push(rsi_arr, rsi12)
array.push(rsi_arr, rsi13)
array.push(rsi_arr, rsi14)
array.push(rsi_arr, rsi15)
array.push(rsi_arr, rsi16)
array.push(rsi_arr, rsi17)
array.push(rsi_arr, rsi18)
array.push(rsi_arr, rsi19)
array.push(rsi_arr, rsi20)
array.push(rsi_arr, rsi21)
array.push(rsi_arr, rsi22)
array.push(rsi_arr, rsi23)
array.push(rsi_arr, rsi24)
array.push(rsi_arr, rsi25)
array.push(rsi_arr, rsi26)
array.push(rsi_arr, rsi27)
array.push(rsi_arr, rsi28)
array.push(rsi_arr, rsi29)
array.push(rsi_arr, rsi30)
array.push(rsi_arr, rsi31)
array.push(rsi_arr, rsi32)
array.push(rsi_arr, rsi33)
array.push(rsi_arr, rsi34)
array.push(rsi_arr, rsi35)
array.push(rsi_arr, rsi36)
array.push(rsi_arr, rsi37)
array.push(rsi_arr, rsi38)
array.push(rsi_arr, rsi39)
array.push(rsi_arr, rsi40)
///////////
// PLOTS //
var tbl = table.new(position.bottom_left, 8, 11, frame_color=#151715, frame_width=1, border_width=2, border_color=color.new(color.white, 100))
if barstate.islast
// Headers for all 4 columns
table.cell(tbl, 0, 0, 'Symbol', width = col_width, text_halign = text.align_center, bgcolor = color.gray, text_color = color.white, text_size = size.small)
table.cell(tbl, 1, 0, 'RSI', width = col_width, text_halign = text.align_center, bgcolor = color.gray, text_color = color.white, text_size = size.small)
table.cell(tbl, 2, 0, 'Symbol', width = col_width, text_halign = text.align_center, bgcolor = color.gray, text_color = color.white, text_size = size.small)
table.cell(tbl, 3, 0, 'RSI', width = col_width, text_halign = text.align_center, bgcolor = color.gray, text_color = color.white, text_size = size.small)
table.cell(tbl, 4, 0, 'Symbol', width = col_width, text_halign = text.align_center, bgcolor = color.gray, text_color = color.white, text_size = size.small)
table.cell(tbl, 5, 0, 'RSI', width = col_width, text_halign = text.align_center, bgcolor = color.gray, text_color = color.white, text_size = size.small)
table.cell(tbl, 6, 0, 'Symbol', width = col_width, text_halign = text.align_center, bgcolor = color.gray, text_color = color.white, text_size = size.small)
table.cell(tbl, 7, 0, 'RSI', width = col_width, text_halign = text.align_center, bgcolor = color.gray, text_color = color.white, text_size = size.small)
// Fill the table with data in 4 columns
for i = 0 to 39
if array.get(u_arr, i)
// Calculate position in the grid (row and column)
col_group = math.floor(i / 10) // Determines which column group (0-3)
row = (i % 10) + 1 // Determines which row (1-10)
col_symbol = col_group * 2 // Symbol column (0, 2, 4, or 6)
col_rsi = col_symbol + 1 // RSI column (1, 3, 5, or 7)
rsi_col = array.get(rsi_arr, i) > rsi_ob ? color.red : array.get(rsi_arr, i) < rsi_os ? color.green : #aaaaaa
// Add the symbol and RSI to the appropriate cells
table.cell(tbl, col_symbol, row, array.get(s_arr, i), text_halign = text.align_center, bgcolor = color.gray, text_color = color.white, text_size = size.small)
table.cell(tbl, col_rsi, row, str.tostring(array.get(rsi_arr, i), "#.##"), text_halign = text.align_center, bgcolor = rsi_col, text_color = color.white, text_size = size.small)
Advantages of Using Arrays in Screeners
- Efficiency: Arrays allow storing and processing large amounts of data dynamically.
- Scalability: Traders can screen multiple stocks without manually defining variables.
- Flexibility: Data can be updated, sorted, and filtered easily based on specific conditions.
The major difference between series and array in Pine Script is how they store and manage data:
Series:
- A series is a built-in Pine Script data type that stores a value for each bar on the chart.
- Every new bar updates the series with a new value.
- Series values can be accessed using the history-referencing operator
[ ]
, e.g.,close[1]
(previous close value). - Used for time-series data like price, indicators, or volume.
Example:
previousClose = close[1] // Accesses the previous bar's close price
Array:
- An array is a collection of values that can store multiple data points dynamically.
- Arrays do not automatically update with each new bar (unlike series).
- Arrays allow adding, removing, and modifying elements manually.
- Used for storing and processing multiple values in a flexible way.
Example:
myArray = array.new_float(0) // Create an empty array
array.push(myArray, close) // Add the current close price to the array
Key Differences:
Feature | Series | Array |
---|---|---|
Data Storage | Stores a value for each bar | Stores multiple values manually |
Auto-update | Updates automatically per bar | Requires manual updates |
Access | Uses value[n] for history | Uses array.get(array, index) |
Flexibility | Fixed historical data structure | Dynamic, allows modifications |
In short, series is best for handling time-series data (e.g., price history), while arrays are useful for dynamic data storage and manipulation, such as building screeners and ranking stocks. 🚀
Conclusion
Arrays are an essential feature in Pine Script for handling multiple data points efficiently. By leveraging arrays, traders can build powerful stock screeners that analyze and display market opportunities dynamically. Whether filtering stocks based on RSI, moving averages, or other indicators, arrays simplify complex operations and enhance script performance.