Rajandran R Creator of OpenAlgo - OpenSource Algo Trading framework for Indian Traders. Building GenAI Applications. Telecom Engineer turned Full-time Derivative Trader. Mostly Trading Nifty, Banknifty, High Liquid Stock Derivatives. Trading the Markets Since 2006 onwards. Using Market Profile and Orderflow for more than a decade. Designed and published 100+ open source trading systems on various trading tools. Strongly believe that market understanding and robust trading frameworks are the key to the trading success. Building Algo Platforms, Writing about Markets, Trading System Design, Market Sentiment, Trading Softwares & Trading Nuances since 2007 onwards. Author of Marketcalls.in

Understanding Arrays and Array Operations in TradingView Pine Script

10 min read

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

  1. Efficiency: Arrays allow storing and processing large amounts of data dynamically.
  2. Scalability: Traders can screen multiple stocks without manually defining variables.
  3. 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:

FeatureSeriesArray
Data StorageStores a value for each barStores multiple values manually
Auto-updateUpdates automatically per barRequires manual updates
AccessUses value[n] for historyUses array.get(array, index)
FlexibilityFixed historical data structureDynamic, 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.

Rajandran R Creator of OpenAlgo - OpenSource Algo Trading framework for Indian Traders. Building GenAI Applications. Telecom Engineer turned Full-time Derivative Trader. Mostly Trading Nifty, Banknifty, High Liquid Stock Derivatives. Trading the Markets Since 2006 onwards. Using Market Profile and Orderflow for more than a decade. Designed and published 100+ open source trading systems on various trading tools. Strongly believe that market understanding and robust trading frameworks are the key to the trading success. Building Algo Platforms, Writing about Markets, Trading System Design, Market Sentiment, Trading Softwares & Trading Nuances since 2007 onwards. Author of Marketcalls.in

First Order and Second Order Option Greeks in Tradingview…

The provided Tradingview Pine Script™ code is an Options Greeks Calculator tailored for use on the TradingView platform. It provides real-time analysis and visualization...
Rajandran R
12 min read

Tradingview Pinescript – Real-Time Option Greeks with Implied Volatility…

Converting an existing Option Greeks model from Amibroker AFL to TradingView Pinescript was an ambitious project, one that involved dealing with complex calculations like...
Rajandran R
9 min read

Leave a Reply

Get Notifications, Alerts on Market Updates, Trading Tools, Automation & More